iOS開發(fā)中伦乔,多線程應(yīng)用方式一般有如下幾種
1 比較高層的醇坝,封裝好的API:NSThread鸟顺。用來(lái)創(chuàng)建非常駐線程以及常駐線程或粮,默認(rèn)支持NSRunLoop機(jī)制。
2 比較高層的朵锣,封裝好的API:NSOperation谬盐。用來(lái)管理他的是NSOperationQueue。每一個(gè)NSOperation都是一個(gè)獨(dú)立的線程诚些。同樣你可以設(shè)置其為常住線程比方while(1)這種惡心的代碼飞傀。
3 比較底層的皇型,簡(jiǎn)單封裝的 C函數(shù)形式的API:GCD---Grand Central Dispatch,據(jù)說(shuō)這個(gè)是比較底層的砸烦,針對(duì)多核cpu做的多線程模型弃鸦,效率比上面兩個(gè)高一些。具體不太清楚幢痘,感興趣的自己做實(shí)驗(yàn)唬格,用事實(shí)說(shuō)話吧。
4 通用的跨平臺(tái)的線程模型:POSIX線程模型颜说,也是C函數(shù)形式的API购岗,pthread族。
下面门粪,我具體談?wù)勎覍?duì)GCD的一些理解喊积,其它的一些東西,網(wǎng)上太多了玄妈,都是抄來(lái)抄去的乾吻,不過(guò)確實(shí)能帶入門,還是表示感謝拟蜻。
dispatch_queue_t 類型的這個(gè)queue到底是個(gè)什么東西溶弟,字面意思理解:首先是一個(gè)queue(隊(duì)列),用來(lái)做什么的呢,存放operation(操作/計(jì)算模塊)的瞭郑,說(shuō)白了就是存放函數(shù)的。
這一點(diǎn)理解可以從他的應(yīng)用方式看得出來(lái):
dispatch_asyn(myQueue,^(param1,param2){
//the fucntion body
NSLog(@"excuting the block body");
}));
那問(wèn)題來(lái)了:假設(shè) 一瞬間 上面這個(gè)語(yǔ)句執(zhí)行了100次鸭你,那這100個(gè)函數(shù)塊兒到底是怎么個(gè)執(zhí)行順序呢屈张?又是不是在同一個(gè)線程上執(zhí)行的呢?
這就引出了 queue的類型:順序queueDISPATCH_QUEUE_SERIAL和并發(fā)queueDISPATCH_QUEUE_CONCURRENT.
1?DISPATCH_QUEUE_SERIAL 測(cè)試
[objc]?view plain?copy
dispatch_queue_t?serialQ?=?dispatch_queue_create("myserialq",?DISPATCH_QUEUE_SERIAL);??
for?(int?i=0;?i<10;?i++)??
{??
????dispatch_async(serialQ,?^{??
NSLog(@"block%d?thread?%@",i,[NSThread?currentThread]);??
????});??
}??
打印log如下:
2015-12-11 17:08:17.477 noarct[10712:242196] block0 thread {number = 2, name = (null)}
2015-12-11 17:08:17.478 noarct[10712:242196] block1 thread {number = 2, name = (null)}
2015-12-11 17:08:17.478 noarct[10712:242196] block2 thread {number = 2, name = (null)}
2015-12-11 17:08:17.478 noarct[10712:242196] block3 thread {number = 2, name = (null)}
2015-12-11 17:08:17.478 noarct[10712:242196] block4 thread {number = 2, name = (null)}
2015-12-11 17:08:17.479 noarct[10712:242196] block5 thread {number = 2, name = (null)}
2015-12-11 17:08:17.479 noarct[10712:242196] block6 thread {number = 2, name = (null)}
2015-12-11 17:08:17.479 noarct[10712:242196] block7 thread {number = 2, name = (null)}
2015-12-11 17:08:17.479 noarct[10712:242196] block8 thread {number = 2, name = (null)}
2015-12-11 17:08:17.479 noarct[10712:242196] block9 thread {number = 2, name = (null)}
2015-12-11 17:08:17.479 noarct[10712:242196] block10 thread {number = 2, name = (null)}
可見(jiàn):DISPATCH_QUEUE_SERIAL 類型的queue上執(zhí)行 多個(gè)代碼塊兒是袱巨,是順序執(zhí)行的阁谆,一個(gè)一個(gè)執(zhí)行的,并且都是在同一個(gè)Thread上執(zhí)行的愉老。也就是說(shuō)DISPATCH_QUEUE_SERIAL 只有一個(gè)線程场绿。
2?DISPATCH_QUEUE_CONCURRENT 測(cè)試
[objc]?view plain?copy
dispatch_queue_t?concurrentQ?=?dispatch_queue_create("myconq",?DISPATCH_QUEUE_CONCURRENT);??
for?(int?i=0;?i<10;?i++)??
{??
????dispatch_async(concurrentQ,?^{??
NSLog(@"block%d?thread?%@",i,[NSThread?currentThread]);??
????});??
}??
打出的log如下:
2015-12-11 17:13:12.842 noarct[10788:246299] block7 thread {number = 6, name = (null)}
2015-12-11 17:13:12.842 noarct[10788:246300] block8 thread {number = 10, name = (null)}
2015-12-11 17:13:12.842 noarct[10788:246287] block0 thread {number = 2, name = (null)}
2015-12-11 17:13:12.842 noarct[10788:246301] block9 thread {number = 11, name = (null)}
2015-12-11 17:13:12.842 noarct[10788:246296] block4 thread {number = 8, name = (null)}
2015-12-11 17:13:12.842 noarct[10788:246297] block5 thread {number = 9, name = (null)}
2015-12-11 17:13:12.842 noarct[10788:246298] block6 thread {number = 7, name = (null)}
2015-12-11 17:13:12.842 noarct[10788:246295] block3 thread {number = 5, name = (null)}
2015-12-11 17:13:12.842 noarct[10788:246288] block1 thread {number = 3, name = (null)}
2015-12-11 17:13:12.842 noarct[10788:246291] block2 thread {number = 4, name = (null)}
如果多運(yùn)行幾次,上面的順序還會(huì)變化嫉入。我們可以看到焰盗,
DISPATCH_QUEUE_CONCURRENT?類型的并發(fā)queue,在裝入多個(gè)函數(shù)模塊的時(shí)候咒林,他的執(zhí)行不一定是根據(jù)裝入順序來(lái)的熬拒,也不一定是在同一個(gè)線程上執(zhí)行的,至于他需要啟動(dòng)多少個(gè)線程來(lái)執(zhí)行 他目前需要執(zhí)行的函數(shù)塊兒垫竞,是由系統(tǒng)自己決定的澎粟,上面看到瞬間加入10個(gè)計(jì)算單元到這個(gè)queue蛀序,沒(méi)有任何其它負(fù)載的情況下,他會(huì)立即處理這10個(gè)計(jì)算單元活烙,于是就啟動(dòng)了10個(gè)線程分別執(zhí)行徐裸。假設(shè),我們額外做一些其它計(jì)算啸盏,他會(huì)啟動(dòng)多少個(gè)線程呢重贺,嘗試如下
3
[objc]?view plain?copy
dispatch_queue_t?concurrentQ?=?dispatch_queue_create("myconq",?DISPATCH_QUEUE_CONCURRENT);??
for?(int?i=0;?i<10;?i++)??
{??
????dispatch_async(concurrentQ,?^{??
NSLog(@"block%d?thread?%@",i,[NSThread?currentThread]);??
????});??
NSLog(@"main?%@",[NSThread?currentThread]);??
}??
打印log如下
2015-12-11 17:20:44.029 noarct[10851:249661] main {number = 1, name = main}
2015-12-11 17:20:44.029 noarct[10851:249705] block0 thread {number = 2, name = (null)}
2015-12-11 17:20:44.029 noarct[10851:249661] main {number = 1, name = main}
2015-12-11 17:20:44.029 noarct[10851:249706] block1 thread {number = 3, name = (null)}
2015-12-11 17:20:44.030 noarct[10851:249661] main {number = 1, name = main}
2015-12-11 17:20:44.030 noarct[10851:249705] block2 thread {number = 2, name = (null)}
2015-12-11 17:20:44.030 noarct[10851:249661] main {number = 1, name = main}
2015-12-11 17:20:44.030 noarct[10851:249706] block3 thread {number = 3, name = (null)}
2015-12-11 17:20:44.030 noarct[10851:249661] main {number = 1, name = main}
2015-12-11 17:20:44.030 noarct[10851:249705] block4 thread {number = 2, name = (null)}
2015-12-11 17:20:44.030 noarct[10851:249661] main {number = 1, name = main}
2015-12-11 17:20:44.030 noarct[10851:249706] block5 thread {number = 3, name = (null)}
2015-12-11 17:20:44.030 noarct[10851:249661] main {number = 1, name = main}
2015-12-11 17:20:44.030 noarct[10851:249705] block6 thread {number = 2, name = (null)}
2015-12-11 17:20:44.112 noarct[10851:249661] main {number = 1, name = main}
2015-12-11 17:20:44.112 noarct[10851:249705] block7 thread {number = 2, name = (null)}
2015-12-11 17:20:44.112 noarct[10851:249661] main {number = 1, name = main}
2015-12-11 17:20:44.112 noarct[10851:249706] block8 thread {number = 3, name = (null)}
2015-12-11 17:20:44.112 noarct[10851:249661] main {number = 1, name = main}
2015-12-11 17:20:44.112 noarct[10851:249705] block9 thread {number = 2, name = (null)}
可見(jiàn),在有其他計(jì)算負(fù)載的時(shí)候宫补,這個(gè)并發(fā)queue就沒(méi)有那么放肆的開啟n個(gè)線程來(lái)做他事兒了檬姥,線程數(shù)量有所減少。
是否可以設(shè)置這種并發(fā)queue的并發(fā)最大執(zhí)行數(shù)量呢粉怕?這個(gè)健民,感興趣的同學(xué)可以自己研究。
好了贫贝,就暫時(shí)說(shuō)這么多秉犹。