GCD中判斷線程內容執(zhí)行完畢

前言:

在使用GCD多線程做操作時始绍,有些時候需要咱們多線程里面的內容全部完成以后话侄,再去刷新頁面內容年堆,這種情況下就需要咱們知道什么時候多線程隊列里面的內容已經執(zhí)行完畢,這里列舉三種方法变丧,希望能對有需要的小伙伴有啟發(fā)痒蓬。

一:信號量

信號量是一個整形值并且具有一個初始計數(shù)值,并且支持兩個操作:信號通知和等待柔昼。當一個信號量被信號通知炎辨,其計數(shù)會被增加聪姿。當一個線程在一個信號量上等待時末购,線程會被阻塞(如果有必要的話),直至計數(shù)器大于零盟榴,然后線程會減少這個計數(shù)。

在GCD中有三個函數(shù)是semaphore的操作擎场,分別是:
dispatch_semaphore_create   創(chuàng)建一個semaphore
dispatch_semaphore_signal   發(fā)送一個信號
dispatch_semaphore_wait    等待信號

第一個函數(shù)是創(chuàng)建一個信號量迅办,我們會給它一個初始值,第二個函數(shù)是發(fā)送信號量姨夹,當調用該函數(shù)的時候,信號量的值會加一峭沦,第三方函數(shù)是等待信號量逃糟,調用等待信號量以后信號量的值會減一,并且當信號量的值小于0時蛉抓,線程就會一直等待剃诅,直到信號量的值大于等于0時才能繼續(xù)執(zhí)行矛辕。

咱們下面逐一介紹這三個函數(shù)的調用以及參數(shù)意義

1.dispatch_semaphore_create

dispatch_samaphore_t dispatch_semaphore_create(long value);
  傳入的參數(shù)為long,輸出一個dispatch_semaphore_t類型且值為value的信號量飞蹂。
 值得注意的是翻屈,這里的傳入的參數(shù)value必須大于或等于0伸眶,否則dispatch_semaphore_create會返回NULL。

2.dispatch_semaphore_signal

    long dispatch_semaphore_signal(dispatch_semaphore_tdsema)
    這里的參數(shù)是第一個函數(shù)創(chuàng)建的信號
  1. dispatch_semaphore_wait

    long dispatch_semaphore_wait(dispatch_semaphore_t dsema,  dispatch_time_t timeout)界酒;第一參數(shù)的是信號嘴秸,第二個參數(shù)是超時時間的設定岳掐,系統(tǒng)給我們了兩         種超時時間設定,一種是 DISPATCH_TIME_NOW  表示當前哭尝; DISPATCH_TIME_FOREVER  表示遙遠的未來剖煌;你可以選擇其中一種也可以自己創(chuàng)建一個超時時間函數(shù)
    

創(chuàng)建超時timeout有兩種方法

第一種方法:

dispatch_time_t dispatch_time(dispatch_time_t when, int64_t delta)逝淹;
其參數(shù)when需傳入一個dispatch_time_t類型的變量栅葡,和一個delta值尤泽。表示when加delta時間就是timeout的時間。

第二種方式:

dispatch_time_t dispatch_walltime(<#const struct timespec * _Nullable when, int64_t delta);
 其參數(shù)when需傳入一個dispatch_time_t類型的變量熊咽,和一個delta值闹丐。表示when加delta時間就是timeout的時間卿拴。

6.關于信號量,一般可以用停車來比喻文狱。

網(wǎng)吧剩余6個座位缘挽,那么即使同時來了6個人也能同時接待。如果此時來了7個人杠袱,那么就有一個人需要等待窝稿。

信號量的值就相當于剩余座位的數(shù)目凿掂,dispatch_semaphore_wait函數(shù)就相當于來了一個人,dispatch_semaphore_signal

就相當于走了一個人庄萎。網(wǎng)絡座位的剩余數(shù)目在初始化的時候就已經指明了(dispatch_semaphore_create(long value))糠涛,

調用一次dispatch_semaphore_signal,剩余的座位就增加一個集漾;調用一次dispatch_semaphore_wait剩余座位就減少一個具篇;

當剩余座位為0時,再來人(即調用dispatch_semaphore_wait)就只能等待驱显。有可能同時有幾個人等待一個座位。有些人

沒有耐心埃疫,給自己設定了一段等待時間伏恐,這段時間內等不到座位就走了,如果等到了就去上網(wǎng)栓霜。而有些人就想站在這里脐湾,所以就一直等下去。

具體到代碼中
假設咱們現(xiàn)在需要做完A叙淌、B秤掌、事件以后才能去做C事件那么咱們就可以仿照下面的做法

#import "ViewController.h"
#import <objc/runtime.h>



@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
[super viewDidLoad];
[self initlizeAppeareces];
}


 - (void)initlizeAppeareces{
//crate的value表示,最多幾個資源可訪問
dispatch_semaphore_t semaphore = dispatch_semaphore_create(2);
dispatch_queue_t quene = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

//任務1
dispatch_async(quene, ^{
    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
    NSLog(@"辦理A事件");
    dispatch_semaphore_signal(semaphore);
});
//任務2
dispatch_async(quene, ^{
    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
    NSLog(@"辦理B事件");
    dispatch_semaphore_signal(semaphore);
});

}

當咱們信號量為2時鹰霍,證明之前的事件都辦理完了闻鉴,咱們就可以做其他的事情了。


二:隊列加group分組
dispatch_group_t group =  dispatch_group_create();

dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

// 執(zhí)行1個耗時的異步操作

});

 dispatch_group_async(group,     dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

// 執(zhí)行1個耗時的異步操作

});

 dispatch_group_notify(group, dispatch_get_main_queue(), ^{

// 等前面的異步操作都執(zhí)行完畢后孟岛,回到主線程...

});

當程序執(zhí)行dispatch_group_notify()函數(shù)時,證明隊列中的任務已經執(zhí)行完了督勺。

第三種方式dispatch_barrier_sync和dispatch_barrier_async

共同點:

1渠羞、等待在它前面插入隊列的任務先執(zhí)行完

2、等待他們自己的任務執(zhí)行完再執(zhí)行后面的任務

不同點:

1智哀、dispatch_barrier_sync將自己的任務插入到隊列的時候次询,需要等待自己的任務結束之后才會繼續(xù)插入被寫在它后面的任務,然后執(zhí)行它們

2瓷叫、dispatch_barrier_async將自己的任務插入到隊列之后屯吊,不會等待自己的任務結束,它會繼續(xù)把后面的任務插入到隊列摹菠,然后等待自己的任務結束后才執(zhí)行后面任務盒卸。

所以調用這兩種方法中的其中一個都會等前面的方法執(zhí)行完以后再執(zhí)行之后的方法,就可以確定隊列中任務是否完成

注: 在信號量的demo編寫過程中我發(fā)現(xiàn)當信號量等于0的時候都崩潰了,如果有知道原因的老鐵歡迎前來分享次氨。

四:將任務添加到串行隊列中

除了像上面那樣處理蔽介,也可以把任務放到各個串行隊列中,并用dispatch group跟蹤其執(zhí)行狀況。然而虹蓄,如果所有任務都排在同一個串行隊列里面犀呼,那么dispatch group就用處不大了。因為此時任務總要逐個執(zhí)行武花,所以只需要在提交完全部任務之后再提交一個塊即可圆凰,這樣做與通過notify函數(shù)等待dispatch group執(zhí)行完畢然后再回調塊是等效的:

dispatch_queue_t queue = dispatch_queue_create("com.effectiveobjectivec.queue",NULL);
for(id object in collection){
   dispatch_async(queue,^{
    [object performTask];
   });
  }
 dispatch_async(queue,^{
    //Continue processing after completing tasks
});

上面這段代碼表明,開發(fā)者未必總需要使用dispatch group体箕。有時候采用單個隊列搭配標準的異步派發(fā)专钉,也可以實現(xiàn)同樣的效果。
筆者為何要在標題中談到"根據(jù)系統(tǒng)資源狀況來執(zhí)行任務"呢累铅?回頭看看向并發(fā)隊列派發(fā)任務的那個例子跃须,就會明白了。為了執(zhí)行隊列中的塊娃兽,GCD會在適當?shù)膶嶋H自動創(chuàng)建新線程菇民。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市投储,隨后出現(xiàn)的幾起案子第练,更是在濱河造成了極大的恐慌,老刑警劉巖玛荞,帶你破解...
    沈念sama閱讀 217,734評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件娇掏,死亡現(xiàn)場離奇詭異,居然都是意外死亡勋眯,警方通過查閱死者的電腦和手機婴梧,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評論 3 394
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來客蹋,“玉大人塞蹭,你說我怎么就攤上這事⊙扰鳎” “怎么了番电?”我有些...
    開封第一講書人閱讀 164,133評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長闽巩。 經常有香客問我钧舌,道長,這世上最難降的妖魔是什么涎跨? 我笑而不...
    開封第一講書人閱讀 58,532評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮崭歧,結果婚禮上隅很,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好叔营,可當我...
    茶點故事閱讀 67,585評論 6 392
  • 文/花漫 我一把揭開白布屋彪。 她就那樣靜靜地躺著,像睡著了一般绒尊。 火紅的嫁衣襯著肌膚如雪畜挥。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,462評論 1 302
  • 那天婴谱,我揣著相機與錄音蟹但,去河邊找鬼。 笑死谭羔,一個胖子當著我的面吹牛华糖,可吹牛的內容都是我干的。 我是一名探鬼主播瘟裸,決...
    沈念sama閱讀 40,262評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼客叉,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了话告?” 一聲冷哼從身側響起兼搏,我...
    開封第一講書人閱讀 39,153評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎沙郭,沒想到半個月后佛呻,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 45,587評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡棠绘,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,792評論 3 336
  • 正文 我和宋清朗相戀三年件相,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片氧苍。...
    茶點故事閱讀 39,919評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡夜矗,死狀恐怖,靈堂內的尸體忽然破棺而出让虐,到底是詐尸還是另有隱情紊撕,我是刑警寧澤,帶...
    沈念sama閱讀 35,635評論 5 345
  • 正文 年R本政府宣布赡突,位于F島的核電站对扶,受9級特大地震影響,放射性物質發(fā)生泄漏惭缰。R本人自食惡果不足惜浪南,卻給世界環(huán)境...
    茶點故事閱讀 41,237評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望漱受。 院中可真熱鬧络凿,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至怨愤,卻和暖如春派敷,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背撰洗。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評論 1 269
  • 我被黑心中介騙來泰國打工篮愉, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人了赵。 一個月前我還...
    沈念sama閱讀 48,048評論 3 370
  • 正文 我出身青樓潜支,卻偏偏與公主長得像,于是被迫代替她去往敵國和親柿汛。 傳聞我的和親對象是個殘疾皇子冗酿,可洞房花燭夜當晚...
    茶點故事閱讀 44,864評論 2 354

推薦閱讀更多精彩內容