[九九Tips]- http://www.reibang.com/users/bab86b3e8aa3/latest_articles
iOS多線程梳理
本篇文章主要梳理iOS多線程相關(guān)基礎(chǔ)概念,使用方法,幾種多線程方案對(duì)比.
進(jìn)程和線程的區(qū)別
進(jìn)程 是指在系統(tǒng)中正在運(yùn)行的一個(gè)應(yīng)用程序,是系統(tǒng)資源的基本分配單位.在內(nèi)存中有完備的數(shù)據(jù)空間和代碼空間,擁有完整的虛擬空間地址.
線程 是進(jìn)程內(nèi)相對(duì)獨(dú)立的可執(zhí)行單元,是操作系統(tǒng)進(jìn)行任務(wù)調(diào)度的基本單元.與父進(jìn)程的其他線程共享該進(jìn)程所擁有的全部代碼空間和全局變量.一個(gè)進(jìn)程至少擁有一個(gè)主線程.
區(qū)別
1.系統(tǒng)開銷:在創(chuàng)建或撤消進(jìn)程時(shí),由于系統(tǒng)都要為之分配和回收資源第股,導(dǎo)致系統(tǒng)的開銷明顯大于創(chuàng)建或撤消線程時(shí)的開銷.
2.資源管理:進(jìn)程有獨(dú)立的地址空間,一個(gè)進(jìn)程崩潰后,在保護(hù)模式下不會(huì)對(duì)其它進(jìn)程產(chǎn)生影響.但線程之間沒有單獨(dú)的地址空間系宜,一個(gè)線程死掉就等于整個(gè)進(jìn)程死掉.所以多進(jìn)程的程序要比多線程的程序健壯沛豌,但在進(jìn)程切換時(shí)庸娱,耗費(fèi)資源較大链峭,效率要差一些畦娄。但對(duì)于一些要求同時(shí)進(jìn)行并且又要共享某些變量的并發(fā)操作,只能用線程,不能用進(jìn)程纷责。
3.通信方式:進(jìn)程間通信主要包括管道捍掺、系統(tǒng)IPC(包括消息隊(duì)列,信號(hào)量,共享存儲(chǔ))撼短、SOCKET.但對(duì)應(yīng)歸于同一進(jìn)程的不同線程來說再膳,使用全局變量進(jìn)行通信效率會(huì)更高。
iOS中幾種多線程方案對(duì)比
iOS有以下四種解決方案:一個(gè)一個(gè)詳細(xì)分析.
1.Pthreads
2.NSThread
3.GCD
4.NSOperationQueue
1.Pthreads
POSIX線程(POSIX threads)曲横,簡(jiǎn)稱Pthreads喂柒,是線程的POSIX標(biāo)準(zhǔn)。該標(biāo)準(zhǔn)定義了創(chuàng)建和操縱線程的一整套API禾嫉。在類Unix操作系統(tǒng)(Unix灾杰、Linux、Mac OS X等)中熙参,都使用Pthreads作為操作系統(tǒng)的線程艳吠。Pthreads是一套純C語言的,通用API,跨平臺(tái)可移植性強(qiáng).
缺點(diǎn):需要手動(dòng)處理線程的各個(gè)狀態(tài)的轉(zhuǎn)換即管理生命周期,比較麻煩.蘋果不推薦使用.
2.NSThread
NSThread是蘋果封裝后的,直接面向?qū)ο蟛僮?但是還需手動(dòng)管理生命周期.
- [NSThread currentThread] 來獲取當(dāng)前線程。
- [NSThread mainThread] 來獲取主線程.
NSThread使用方法簡(jiǎn)單,但是應(yīng)用場(chǎng)景有限.
3.GCD
GCD為Grand Central Dispatch的縮寫孽椰。Grand Central Dispatch (GCD)是Apple開發(fā)的一個(gè)多核編程的較新的解決方法昭娩。
GCD自動(dòng)管理線程的生命周期(創(chuàng)建線程、調(diào)度任務(wù)黍匾、銷毀線程).
GCD有兩個(gè)很重要的概念:任務(wù)和隊(duì)列.
-
任務(wù) 在 GCD 中就是一個(gè) Block栏渺,任務(wù)有兩種執(zhí)行方式:同步執(zhí)行 和 異步執(zhí)行.
- 同步(sync) 操作,它會(huì)阻塞當(dāng)前線程并等待 Block 中的任務(wù)執(zhí)行完畢锐涯,然后當(dāng)前線程才會(huì)繼續(xù)往下運(yùn)行磕诊。同步任務(wù):不會(huì)另開線程.
- 異步(async)操作,當(dāng)前線程會(huì)直接往下執(zhí)行纹腌,它不會(huì)阻塞當(dāng)前線程霎终。異步任務(wù):會(huì)另開線程.
-
隊(duì)列 用于存放任務(wù)。一共有兩種隊(duì)列升薯, 串行隊(duì)列 和 并行隊(duì)列莱褒。
- 串行隊(duì)列,放到串行隊(duì)列的任務(wù)覆劈,GCD 會(huì) FIFO(先進(jìn)先出) 地取出來一個(gè)保礼,執(zhí)行一個(gè),然后取下一個(gè)责语,這樣一個(gè)一個(gè)的執(zhí)行炮障。
- 并行隊(duì)列,放到并行隊(duì)列的任務(wù)坤候,GCD 也會(huì) FIFO的取出來胁赢,但不同的是,它取出來一個(gè)就會(huì)放到別的線程白筹,然后再取出來一個(gè)又放到另一個(gè)的線程智末。這樣由于取的動(dòng)作很快虾标,忽略不計(jì),看起來宙地,所有的任務(wù)都是一起執(zhí)行的搂蜓。不過需要注意,GCD 會(huì)根據(jù)系統(tǒng)資源控制并行的數(shù)量由蘑,所以如果任務(wù)很多闽寡,它并不會(huì)讓所有任務(wù)同時(shí)執(zhí)行。也就是說并行就是開很多線程一個(gè)一個(gè)執(zhí)行
- 主隊(duì)列: 這是一個(gè)特殊的 串行隊(duì)列.它用于刷新 UI尼酿,任何需要刷新 UI 的工作都要在主隊(duì)列執(zhí)行.
- 創(chuàng)建隊(duì)列
//第一個(gè)參數(shù)是標(biāo)識(shí)符爷狈,用于 DEBUG 的時(shí)候標(biāo)識(shí)唯一的隊(duì)列,可以為空. /** 第二個(gè)參數(shù)用來表示創(chuàng)建的隊(duì)列是串行的還是并行的. DISPATCH_QUEUE_SERIAL 或 NULL 表示創(chuàng)建串行隊(duì)列; DISPATCH_QUEUE_CONCURRENT 表示創(chuàng)建并行隊(duì)列. **/ dispatch_queue_t queue = dispatch_queue_create("tk.bourne.testQueue", NULL);
4.NSOperationQueue
NSOperation 是蘋果公司對(duì) GCD 的封裝裳擎,完全面向?qū)ο?
NSOperation 和 NSOperationQueue 分別對(duì)應(yīng) GCD 的 任務(wù) 和 隊(duì)列 .
- 1.NSOperationQueue不分并行和串行,NSOperationQueue 有一個(gè)參數(shù) maxConcurrentOperationCount 最大并發(fā)數(shù)涎永,用來設(shè)置最多可以讓多少個(gè)任務(wù)同時(shí)執(zhí)行。當(dāng)你把它設(shè)置為 1 的時(shí)候鹿响,就是串行.
- 2.NSOperation添加依賴羡微。可以使用 removeDependency 來解除依賴關(guān)系抢野。這樣就能控制任務(wù)的執(zhí)行順序.
//1.任務(wù)一:
NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{
[NSThread sleepForTimeInterval:1.0];
}];
//2.任務(wù)二:
NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{
[NSThread sleepForTimeInterval:1.0];
}];
//3.任務(wù)三:
NSBlockOperation *operation3 = [NSBlockOperation blockOperationWithBlock:^{
[NSThread sleepForTimeInterval:1.0];
}];
//4.設(shè)置依賴
[operation2 addDependency:operation1]; //任務(wù)二依賴任務(wù)一
[operation3 addDependency:operation2]; //任務(wù)三依賴任務(wù)二
//5.創(chuàng)建隊(duì)列并加入任務(wù)
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperations:@[operation3, operation2, operation1] waitUntilFinished:NO];
以上部分內(nèi)容參考該博客:http://www.reibang.com/p/0b0d9b1f1f19