淺談GCD的線程依賴

之前對線程使用的不是太多,今天專門抽時間看了下GCD的線程使用。好記性不如爛筆頭,整理下來方便以后復(fù)習(xí)使用,也與和大家分享一下。第一次寫簡書,水平有限,歡迎大家多多給出建議,互相學(xué)習(xí)。成長的路上,與大家同勉~~~~

下面進(jìn)入正題

需求舉例:有三個任務(wù)需要順序執(zhí)行:任務(wù)1-->任務(wù)2-->任務(wù)3

實(shí)現(xiàn)方式一:(線程組)

①.創(chuàng)建線程組:dispatch_group_t group = dispatch_group_create();

②.創(chuàng)建隊(duì)列:dispatch_queue_t queue = dispatch_queue_create(0, 0);

③.把任務(wù)提交到隊(duì)列中執(zhí)行:dispatch_group_enter(group);

? ????????????????????????????????????????????? dispatch_async(queue, ^{

? ? ? ? ????????????????????????????????????????????????[NSThread sleepForTimeInterval:2];

? ? ? ? ????????????????????????????????????????????????NSLog(@"任務(wù)1執(zhí)行");

? ? ? ????????????????????????????????????????????????? dispatch_group_leave(group);

? ????????????????????????????????????????????? });

????????????????????????????????????????? ? ????dispatch_barrier_async(queue, ^{

? ? ? ????????????????????????????????????????? ? ? ????? NSLog(@"任務(wù)2執(zhí)行");

? ? ????????????????????????????????????? ????? });

④.監(jiān)聽任務(wù)1和任務(wù)二是否執(zhí)行完:?dispatch_group_notify(group, dispatch_get_global_queue(0, 0), ^{

? ? ? ? NSLog(@"任務(wù)3執(zhí)行");

? ? });

打印結(jié)果為:任務(wù)1執(zhí)行---------任務(wù)2執(zhí)行----------任務(wù)3執(zhí)行

劃重點(diǎn):①dispatch_barrier_async(queue, ^{? })方法(我一般叫做柵欄或格柵),該方法的使用要求queue為自己創(chuàng)建的隊(duì)列,不要使用全局隊(duì)列和主隊(duì)列,否則就失去使用柵欄(或者格柵)方法的意義;②dispatch_group_notify(group, dispatch_get_global_queue(0, 0), ^{? ? })方法可以監(jiān)聽任務(wù)1和任務(wù)2是否完全執(zhí)行完畢,只有前面的任務(wù)執(zhí)行完畢之后才會執(zhí)行任務(wù)3,任務(wù)3最常見的應(yīng)用就是請求完數(shù)據(jù),用于主線程的數(shù)據(jù)刷新或者繼續(xù)進(jìn)行其他操作;③dispatch_group_enter(group)方法和dispatch_group_leave(group)方法是成對使用的,該方法會被線程監(jiān)聽,可以比較安全的保證任務(wù)1和任務(wù)2妥妥的執(zhí)行完畢之后再執(zhí)行任務(wù)3。

實(shí)現(xiàn)方式二:(信號量)

①.創(chuàng)建倆信號量:?dispatch_semaphore_t sem1 = dispatch_semaphore_create(0);

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? dispatch_semaphore_t sem2 = dispatch_semaphore_create(0);

②.執(zhí)行任務(wù):

dispatch_async(dispatch_get_global_queue(0, 0), ^{

? ? ? ? dispatch_semaphore_wait(sem1, DISPATCH_TIME_FOREVER);

? ? ? ? NSLog(@"任務(wù)3");

? ? });

? ? dispatch_async(dispatch_get_global_queue(0, 0), ^{

? ? ? ? dispatch_semaphore_wait(sem2, DISPATCH_TIME_FOREVER);

? ? ? ? NSLog(@"任務(wù)2");

? ? ? ? dispatch_semaphore_signal(sem1);

? ? });

? ? dispatch_async(dispatch_get_global_queue(0, 0), ^{

? ? ? ? NSLog(@"任務(wù)1");

? ? ? ? dispatch_semaphore_signal(sem2);

? ? });

打印結(jié)果為:任務(wù)1執(zhí)行---------任務(wù)2執(zhí)行----------任務(wù)3執(zhí)行

劃重點(diǎn):①dispatch_semaphore_t 創(chuàng)建的信號量sem1和sem2初始值給的都是0;? ? ? ? ? ? ? ? ? ?②第一個異步任務(wù)中dispatch_semaphore_wait(sem1, DISPATCH_TIME_FOREVER)方法會檢查sem1的信號量值是否>0如果>0就會執(zhí)行任務(wù)3,否者就會阻塞線程,任務(wù)3不會執(zhí)行;? ? ? ? ? ?③同理,第二個異步任務(wù)中dispatch_semaphore_wait(sem0, DISPATCH_TIME_FOREVER)方法會檢查sem0的信號量值是否>0如果>0就會執(zhí)行任務(wù)2,否者就會阻塞線程,任務(wù)2不會執(zhí)行;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ④?第三個異步任務(wù)中先執(zhí)行任務(wù)1,然后dispatch_semaphore_signal(sem2)方法會給sem2信號量+1,sem2信號量+1后,第二個異步任務(wù)接收到信號,就會開始執(zhí)行任務(wù)2,然后再執(zhí)行?dispatch_semaphore_signal(sem1)給sem1增加信號量,同時,sem2的信號量會自動-1,變成0,后續(xù)如果不再給sem2增加信號量,就會一直阻塞下去,不再繼續(xù)執(zhí)行;? ? ? ? ? ? ? ? ? ? ? ? ? ? ?⑤sem1信號量+1后,第一個異步任務(wù)接收到信號,就會開始執(zhí)行任務(wù)3,同時,sem1的信號量會自動-1,變成0,后續(xù)如果不再給sem2增加信號量,就會一直阻塞下去,不再繼續(xù)執(zhí)行 。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容