進程和線程

進程和線程的區(qū)別

1.進程是具有一定獨立功能的程序關于某個數據集合上的一次運行活動偷崩,它是系統(tǒng)資源分配的基本單位。線程是處理機調度的最小單位帚呼。
2.進程有自己獨立的地址空間;進程至少有一個線程掏缎,它們共享進程的地址空間,同一個進程內的線程共享進程的資源煤杀。

多線程是指從軟件或者硬件上實現多個線程并發(fā)執(zhí)行的技術眷蜈。具有多線程能力的計算機因有硬件支持而能夠在同一時間執(zhí)行多于一個線程,進而提升整體處理性能沈自。其本質上并不是同時執(zhí)行多個程序酌儒,而是操作系統(tǒng)根據合理的算法在較短的時間內完成各個線程之間的切換,每個線程執(zhí)行一段時間后枯途,切換到下一個線程執(zhí)行忌怎。

多線程的優(yōu)點:能適當提高程序的執(zhí)行效率;能適當提高資源利用率(CPU柔袁、內存利用率)呆躲。

多線程的缺點:開啟線程需要占用一定的內存空間(默認情況下,主線程占用1M捶索,子線程占用512KB)插掂,如果開啟大量的線程,會占用大量的內存空間,降低程序的性能辅甥;線程越多酝润,CPU在調度線程上的開銷就越大;程序設計更加復雜:比如線程之間的通信璃弄、多線程的數據共享要销。

使用線程可以把占據時間長的程序中的任務放到后臺去處理用戶界面可以更加吸引人,這樣比如用戶點擊了一個按鈕去觸發(fā)某些事件的處理夏块,可以彈出一個進度條來顯示處理的進度程序的運行速度可能加快在一些等待的任務實現上如用戶輸入疏咐、文件讀寫和網絡收發(fā)數據等。

iOS中實現多線程的方式

NSThread

輕量級別的多線程技術脐供,需要我們手動來管理線程浑塞。提供的方法比較少,例如串行政己,并發(fā)執(zhí)行這些實現起來相當困難酌壕。開辟子線程的方法有兩種,一個是初始化需要手動開啟歇由,也就是調用start方法卵牍,并且有返回值,返回的就是NSThread對象沦泌,可以設置線程名稱糊昙,設置線程的優(yōu)先級等一些參數。另一種是便利構造器的方法開辟子線程無返回值赦肃,會自動啟動線程溅蛉。不需要手動調用start方法。

//通過NSThread開辟子線程
//object:這個是回調方法的參數
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(testThread) object:nil];
thread.name = @"我是第二條線程";
//調整thread的優(yōu)先級他宛,線程權限的范圍值為0~1船侧,值越大優(yōu)先級越高,默認值為0.5厅各。由于是概率镜撩,所以并不能很準確的實現我們先要的執(zhí)行順序。
thread.threadPriority = 0.8;
//當使用初始化方法創(chuàng)建的子線程队塘,需要start啟動
[thread start];

//取消當前已經啟動的線程
//    [thread1 cancel];

線程的回調方法

- (void)testThread
{
    //如果子線程是我們手動開辟的袁梗,那么就需要我們來回收它所占用的資源。
    @autoreleasepool {
        NSLog(@"%@",[NSThread currentThread]);
        double sum = 0;
        for (double i = 0; i < 500000000; i++) {
            sum += i;
        }
        //[NSThread currentThread]獲取當前線程
        NSLog(@"sum------%f------%@",sum,[NSThread currentThread]);
}

NSObject

只要是NSObject的子類或者對象都可以通過調用方法進入子線程和主線程憔古,其實這些方法所開辟的子線程也是NSThread的另一種體現方式遮怜。
開辟子線程:
[self performSelectorInBackground:@selector(aaa) withObject:nil];
進入主線程:
[self performSelectorOnMainThread:@selector(bbb) withObject:nil waitUntilDone:YES];

NSOperationQueue

它使OC級別的封裝,是將一組事件添加到隊列中鸿市,如果想讓這組事件在主線程中執(zhí)行锯梁,那么就需要主隊列[NSOperationQueue mainQueue];如果想要將一組事件在子線程中執(zhí)行那么就需要其他隊列[[NSOperation alloc] init];NSOperation就是事件即碗,它本身是一個抽象類,如果需要實現具體操作陌凳,需要它的兩個子類:NSInvocationOperation和NSBlockOperation剥懒;事件本身和線程無關,只是看你將它加到那種隊列中或者將事件放入主線程中合敦。如果在隊列中想要使得事件順序執(zhí)行初橘,需要給事件添加依賴關系,添加依賴關系的時候兩個事件不能互為依賴充岛。也可以設置事件的優(yōu)先級來提高它先執(zhí)行的概率保檐,但是不準確。還可以設置隊列的最大并發(fā)執(zhí)行的個數崔梗,來使得事件順序執(zhí)行展东。NSThread需要程序員手動管理,NSOperationQueue會自動管理線程炒俱。

- (void)operationQueue
{
    //這個類只是執(zhí)行一個操作,本身和線程無關爪膊,也就是把對象放到哪個線程之中权悟,它就在哪個線程中執(zhí)行。
    NSInvocationOperation *invocation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(invocationAction) object:nil];
    //該事件需要手動啟動
    //    [invocation start];
    
    //通過block方式來增加事件
    NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"block------%@",[NSThread currentThread]);
    }];
    //block方式的operation可以增加一組額外的block事件,通過這種方式為blockOperation添加的block事件的執(zhí)行順序無法掌控推盛,所在的線程也無法掌控峦阁。
    for (int i = 0; i < 5; i++) {
        [blockOperation addExecutionBlock:^{
            NSLog(@"execuBlock------%@",[NSThread currentThread]);
        }];
    }
    //當所有的block事件都執(zhí)行完成,我們可以讓它發(fā)出通知耘成,告訴我們所有事件都執(zhí)行完成
    blockOperation.completionBlock = ^{
        NSLog(@"不管上面怎么執(zhí)行榔昔,它肯定是最后一個執(zhí)行的");
        NSLog(@"%@",[NSThread currentThread]);
    };
    //只要是事件都需要手動啟動
    //    [blockOperation start];
    
    //事件不具備開辟線程的能力,所以我們需要配合queue來使用它瘪菌,queue就是隊列撒会,其實隊列就是用來處理一組時間,事件加到隊列中师妙,就不需要手動啟動诵肛,也不用我們來關心它開辟線程之后的消耗,這些事情都是隊列幫助我們處理默穴。隊列一般分為主隊列和其他隊列
    //其他隊列怔檩,可以將時間在除主線程的其他線程中處理,而且執(zhí)行順序不定(并發(fā)執(zhí)行)通過設置最大并發(fā)數或者事件依賴蓄诽,就可以將一組事件在子線程中順序執(zhí)行薛训,達到串行的目的。
    //    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    
    //主隊列仑氛,是將一組時間在主線程中執(zhí)行乙埃,不用設置任何屬性闸英,一組事件都會順序執(zhí)行。
    NSOperationQueue *queue = [NSOperationQueue mainQueue];
    
    //我們需要按照順序執(zhí)行一組事件膊爪,有兩種方式
    //第一種自阱,設置該隊列最大并發(fā)執(zhí)行事件的個數,該屬性默認值為-1米酬,該隊列中有多少個事件沛豌,就并發(fā)執(zhí)行多少個。如果并發(fā)事件設置為1赃额,那就是一次只執(zhí)行一個事件
    //    queue.maxConcurrentOperationCount = 1;
    
    //第二種方式加派,就是添加事件依賴,事件依賴意思就是跳芳,當一個時間執(zhí)行完畢才會執(zhí)行另一個事件芍锦,這里就是先執(zhí)行blockOperation,在執(zhí)行invocation
    [blockOperation addDependency:invocation];
    
    //給隊列中添加事件
    [queue addOperation:invocation];
    [queue addOperation:blockOperation];
}

GCD

GCD效率比operationQueue要高一些飞盆,功能更強大娄琉,目前有替代其他多線程方式的趨勢,它處理事件主要是通過隊列來執(zhí)行吓歇。分為兩種隊列孽水,一種是串行,一種是并行城看。系統(tǒng)提供給我們的一種是全局隊列女气,一種是主隊列。添加事件的函數為:dispatch_async();一般我們都是用異步添加時間测柠,最重要的原因是它不會阻塞當前線程炼鞠。全局隊列中所添加的異步時間肯定都是在子線程中的。主隊列中添加的事件不管是異步還是同步都是在主線程中轰胁。
同步函數不具備開啟線程的能力谒主,無論是什么隊列都不會開啟線程;異步函數具備開啟線程的能力赃阀,開啟幾條線程由隊列決定(串行隊列只會開啟一條新的線程瘩将,并發(fā)隊列會開啟多條線程)。
同步函數:
(1)并發(fā)隊列:不會開線程
(2)串行隊列:不會開線程
異步函數:
(1)并發(fā)隊列:能開啟N條線程
(2)串行隊列:開啟1條線程
補充:凡是函數中凹耙,各種函數名中帶有create\copy\new\retain等字眼姿现,都需要在不需要使用這個數據的時候進行release。
GCD的數據類型在ARC的環(huán)境下不需要再做release肖抱。
異步函數具備開線程的能力备典,但不一定會開線程。

串行隊列

//創(chuàng)建一個串行隊列
//dispatch_queue_create函數是用來創(chuàng)建隊列使用意述,第一個參數為該隊列的標簽缘缚;第二個參數為該隊列類型,通常設置為NULL
dispatch_queue_t serialQueue = dispatch_queue_create("串行", DISPATCH_QUEUE_SERIAL);
//給該隊列添加事件
//第一個參數為該事件所在的隊列广凸;第二個參數為block,該時間所要做的處理
dispatch_async(serialQueue, ^{
    NSLog(@"洛洛出生了---%@",[NSThread currentThread]);
});

并行隊列

//創(chuàng)建一個并行隊列
dispatch_queue_t queue = dispatch_queue_create("concurrent", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
     NSLog(@"我是第1個---%@",[NSThread currentThread]);
});
//此函數會阻塞當前線程潮针,對主線程無影響
dispatch_barrier_async(queue, ^{
    NSLog(@"我在執(zhí)行---%@",[NSThread currentThread]);
});

系統(tǒng)提供的全局隊列

- (void)globalQueue
{
     //得到系統(tǒng)的提供的全局隊列
    //dispatch_get_global_queue(0, 0);
    //第一個參數為該全局隊列的優(yōu)先級
    //第二個參數暫時沒用,是系統(tǒng)為了后面擴展來使用倚喂,在將來的某一天會使用到每篷。直接賦值為0就可以
    dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(globalQueue, ^{
        NSLog(@"正在網絡下載或者一些其他耗時的操作");
        //耗時操作完成之后為主線程更新UI,GCD回主線程方式
        //要得到主隊列端圈,和operationQueue中的mainQueue是一樣的概念
        dispatch_queue_t mainQueue = dispatch_get_main_queue();
        dispatch_async(mainQueue, ^{
            //在此處進行UI刷新
            NSLog(@"mainQueue---%@",[NSThread currentThread]);
        });
    });
}

GCD中代碼的延時執(zhí)行

//第一個參數是說從什么時候開始計時
//多少秒之后執(zhí)行block中的操作
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
   NSLog(@"5秒之后執(zhí)行");
});

NSObject代碼的延時執(zhí)行

[self performSelector:@selector(afterAction:) withObject:@"五秒之后執(zhí)行" afterDelay:5];
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末焦读,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子舱权,更是在濱河造成了極大的恐慌矗晃,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,807評論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件宴倍,死亡現場離奇詭異张症,居然都是意外死亡,警方通過查閱死者的電腦和手機鸵贬,發(fā)現死者居然都...
    沈念sama閱讀 95,284評論 3 399
  • 文/潘曉璐 我一進店門吠冤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人恭理,你說我怎么就攤上這事」洌” “怎么了颜价?”我有些...
    開封第一講書人閱讀 169,589評論 0 363
  • 文/不壞的土叔 我叫張陵,是天一觀的道長诉濒。 經常有香客問我周伦,道長,這世上最難降的妖魔是什么未荒? 我笑而不...
    開封第一講書人閱讀 60,188評論 1 300
  • 正文 為了忘掉前任专挪,我火速辦了婚禮,結果婚禮上片排,老公的妹妹穿的比我還像新娘寨腔。我一直安慰自己,他們只是感情好率寡,可當我...
    茶點故事閱讀 69,185評論 6 398
  • 文/花漫 我一把揭開白布迫卢。 她就那樣靜靜地躺著,像睡著了一般冶共。 火紅的嫁衣襯著肌膚如雪乾蛤。 梳的紋絲不亂的頭發(fā)上每界,一...
    開封第一講書人閱讀 52,785評論 1 314
  • 那天,我揣著相機與錄音家卖,去河邊找鬼眨层。 笑死,一個胖子當著我的面吹牛上荡,可吹牛的內容都是我干的趴樱。 我是一名探鬼主播,決...
    沈念sama閱讀 41,220評論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼榛臼,長吁一口氣:“原來是場噩夢啊……” “哼伊佃!你這毒婦竟也來了?” 一聲冷哼從身側響起沛善,我...
    開封第一講書人閱讀 40,167評論 0 277
  • 序言:老撾萬榮一對情侶失蹤航揉,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后金刁,有當地人在樹林里發(fā)現了一具尸體帅涂,經...
    沈念sama閱讀 46,698評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,767評論 3 343
  • 正文 我和宋清朗相戀三年尤蛮,在試婚紗的時候發(fā)現自己被綠了媳友。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,912評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡产捞,死狀恐怖醇锚,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情坯临,我是刑警寧澤焊唬,帶...
    沈念sama閱讀 36,572評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站看靠,受9級特大地震影響赶促,放射性物質發(fā)生泄漏。R本人自食惡果不足惜挟炬,卻給世界環(huán)境...
    茶點故事閱讀 42,254評論 3 336
  • 文/蒙蒙 一鸥滨、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧谤祖,春花似錦婿滓、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,746評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至容客,卻和暖如春秕铛,著一層夾襖步出監(jiān)牢的瞬間约郁,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,859評論 1 274
  • 我被黑心中介騙來泰國打工但两, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留鬓梅,地道東北人。 一個月前我還...
    沈念sama閱讀 49,359評論 3 379
  • 正文 我出身青樓谨湘,卻偏偏與公主長得像绽快,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子紧阔,可洞房花燭夜當晚...
    茶點故事閱讀 45,922評論 2 361

推薦閱讀更多精彩內容