C++ 線程(串行 并行 同步 異步)詳解
在東港等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強發(fā)展的系統(tǒng)性、市場前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供網(wǎng)站建設(shè)、成都網(wǎng)站建設(shè) 網(wǎng)站設(shè)計制作定制網(wǎng)站設(shè)計,公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),高端網(wǎng)站設(shè)計,營銷型網(wǎng)站建設(shè),外貿(mào)網(wǎng)站制作,東港網(wǎng)站建設(shè)費用合理。
看了很多關(guān)于這類的文章,一直沒有總結(jié)。不總結(jié)的話就會一直糊里糊涂,以下描述都是自己理解的非官方語言,不一定嚴(yán)謹,可當(dāng)作參考。
首先,進程可理解成一個可執(zhí)行文件的執(zhí)行過程。在ios app上的話我們可以理解為我們的app的.ipa文件執(zhí)行過程也即app運行過程。殺掉app進程就殺掉了這個app在系統(tǒng)里運行所占的內(nèi)存。
線程:線程是進程的最小單位。一個進程里至少有一個主線程。就是那個main thread。非常簡單的app可能只需要一個主線程即UI線程。當(dāng)然大部分還是會有一些子線程的,比如如果你用了AFNetWorking,你的請求都是開辟了子線程。
關(guān)于串行,并行,同步,異步,我還是以下面代碼的方式做個說明。
首先button點擊事件運行在主線程里,先是在主線程里做了打印了一句話,然后創(chuàng)建了一個串行或者并行的隊列,之后連續(xù)創(chuàng)建了3個同步或者異步的block任務(wù)放入此隊列中,最后再在主線程里打印一句話。
- (IBAction)serialSync:(id)sender { NSLog(@"start log in main thread"]); dispatch_queue_t myQueue = dispatch_queue_create("myQueue", NULL); for (NSInteger n = 0; n < 3; n++) { dispatch_sync(myQueue, ^{ for (NSInteger i = 0; i < 500000000; i++) { if (i == 0) { NSLog(@"串行同步任務(wù)%ld -> 開始%@",n,[NSThread currentThread]); } if (i == 499999999) { NSLog(@"串行同步任務(wù)%ld -> 完成",(long)n); } } }); } NSLog(@"阻塞我沒有?當(dāng)前線程%@",[NSThread currentThread]); } - (IBAction)serialAsync:(id)sender { NSLog(@"start log in main thread"]); dispatch_queue_t myQueue = dispatch_queue_create("myQueue", NULL);//創(chuàng)建一個串行隊列 for (NSInteger n = 0; n < 3; n++) { dispatch_async(myQueue, ^{ for (NSInteger i = 0; i < 500000000; i++) { if (i == 0) { NSLog(@"串行異步任務(wù)%ld -> 開始%@",n,[NSThread currentThread]); } if (i == 499999999) { NSLog(@"串行異步任務(wù)%ld -> 完成",(long)n); } } }); } NSLog(@"阻塞我沒有?當(dāng)前線程%@",[NSThread currentThread]); } - (IBAction)concurrentSync:(id)sender { NSLog(@"start log in main thread"]); dispatch_queue_t myQueue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT); for (NSInteger n = 0; n < 3; n++) { dispatch_sync(myQueue, ^{ for (NSInteger i = 0; i < 500000000; i++) { if (i == 0) { NSLog(@"并行同步任務(wù)%ld -> 開始%@",(long)n,[NSThread currentThread]); } if (i == 499999999) { NSLog(@"并行同步任務(wù)%ld -> 完成",(long)n); } } }); } NSLog(@"阻塞我沒有?當(dāng)前線程%@",[NSThread currentThread]); } - (IBAction)concurrentAsync:(id)sender { NSLog(@"start log in main thread"]); dispatch_queue_t myQueue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT); for (NSInteger n = 0; n < 3; n++) { dispatch_async(myQueue, ^{ for (NSInteger i = 0; i < 500000000; i++) { if (i == 0) { NSLog(@"并行異步任務(wù)%ld -> 開始%@",n,[NSThread currentThread]); } if (i == 499999999) { NSLog(@"并行異步任務(wù)%ld -> 完成",(long)n); } } }); } NSLog(@"阻塞我沒有?當(dāng)前線程%@",[NSThread currentThread]); }
最后的結(jié)果如圖:
其中我把第一句打印和最后一句打印用玫紅色表示,它們都運行在當(dāng)前線程。
方框表示隊列,3個block任務(wù)分別為3種不同的顏色。
可以看出:
串行即上一個block任務(wù)執(zhí)行完畢下一個任務(wù)才加入到隊列中。
并行即其中的任務(wù)同時加入到隊列中。
從運行結(jié)果來看
第一個圖只有一個主線程:
3個block都是同步即都阻塞當(dāng)前線程,所以最后那句打印的任務(wù)就在3個block運行完之后。
3個block又是串行,所以一個一個運行
第二個圖有2個線程即一個主線程一個子線程:
3個block都是異步,沒有任務(wù)阻塞當(dāng)前線程。所以最后那句打印是在第一句打印后就可以開始執(zhí)行的。
3個block都是異步,異步會創(chuàng)建新的線程即至少有一個子線程。
3個block是串行,只有一個任務(wù)做完才會加另一個任務(wù)入隊列,所以只需一個子線程。
第三個圖只有一個主線程:
3個block都是同步即都阻塞當(dāng)前線程,所以最后那句打印的任務(wù)就在3個block運行完之后。
3個block是并行,同時被加入隊列中。
3個block都是同步,由于同步意味著等待,所以任務(wù)的執(zhí)行表現(xiàn)為順序執(zhí)行,其實是一起加進去的但是等待的,跟串行的區(qū)別是串行是別的任務(wù)做完才把它加進隊列中。
第四個圖有多個線程:
3個block都是異步,沒有任務(wù)阻塞當(dāng)前線程。所以最后那句打印是在第一句打印后就可以開始執(zhí)行的。
3個block都是異步,異步會創(chuàng)建新的線程即至少有一個子線程。
3個block是并行,需創(chuàng)建多個子線程才能保證任務(wù)同時執(zhí)行。
再看一張圖:其中第一個異步為玫紅色,兩個同步分別以紫色黃色表示,兩個異步分別以綠色棕色表示,隊列后面的當(dāng)前線程動作為橘色。虛線代表等待。上面代表串行,下面是并行。
由此圖可以看出:
同步block會阻塞當(dāng)前線程,即會在當(dāng)前線程中運行。(這里的當(dāng)前線程為主線程所以會看到UI卡?。?/p>
異步block會開辟新的線程。
在串行隊列中,異步block任務(wù)用的是同一個子線程,因為需要等待任務(wù)一個一個地執(zhí)行,不需要多個線程。
在并行隊列中,異步block任務(wù)同時執(zhí)行,系統(tǒng)為其分配線程。圖中的例子因第一個異步操作在第二個開始前已經(jīng)結(jié)束了,所以并不是多少個異步操作就創(chuàng)建多少線程,主要還是看需要。
感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!