介紹
信號量是一個整形值并且具有一個初始計數(shù)值蜡吧,并且支持兩個操作:信號通知和等待。當(dāng)一個信號量被信號通知占键,其計數(shù)會被增加昔善。當(dāng)一個線程在一個信號量上等待時,線程會被阻塞(如果有必要的話)捞慌,直至計數(shù)器大于零耀鸦,然后線程會減少這個計數(shù)。
在GCD中有三個函數(shù)是semaphore的操作啸澡,分別是:
dispatch_semaphore_create 創(chuàng)建一個semaphore
dispatch_semaphore_signal 發(fā)送一個信號
dispatch_semaphore_wait 等待信號
dispatch_semaphore_create
1袖订、作用:創(chuàng)建具有初始值的計數(shù)信號量
2、使用:
//需要多個線程進(jìn)行協(xié)調(diào)工作的時候嗅虏,初始值傳0,用于阻塞當(dāng)前線程洛姑,比如兩個異步操作串行執(zhí)行
dispatch_semaphore_create(0);
//管理一個有限的線程池,初始值n > 0,線程池的大小與初始值相等
dispatch_semaphore_create(n);
dispatch_semaphore_wait
1皮服、作用:等待(減少)一個信號
2楞艾、使用:
//信號量semaphore計數(shù)減1。如果結(jié)果值小于零龄广,這個函數(shù)會阻塞當(dāng)前線程等待一個信號硫眯。注意:semaphore不能為NULL
//dispatch_time_t 可以自定義也可以使用系統(tǒng)內(nèi)置的連個宏(DISPATCH_TIME_NOW/DISPATCH_TIME_FOREVER)
dispatch_semaphore_wait(semaphore, dispatch_time_t);
dispatch_semaphore_signal
1、作用:發(fā)送(增加)一個信號
2择同、使用:
//信號量semaphore計數(shù)加1两入,如果在此之前semaphore已經(jīng)小于0,在返回之前喚醒了一個等待線程敲才,注意:semaphore不能為NULL
dispatch_semaphore_signal(semaphore);
案例
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_CONCURRENT);
NSLog(@"開始1");
dispatch_async(queue, ^{
NSLog(@"執(zhí)行1");
dispatch_semaphore_signal(semaphore);
NSLog(@"釋放1");
});
NSLog(@"等待1");
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
NSLog(@"開始2");
dispatch_async(queue, ^{
NSLog(@"執(zhí)行2");
dispatch_semaphore_signal(semaphore);
NSLog(@"釋放2");
});
NSLog(@"等待2");
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
NSLog(@"開始3");
dispatch_async(queue, ^{
NSLog(@"執(zhí)行3");
dispatch_semaphore_signal(semaphore);
NSLog(@"釋放3");
});
NSLog(@"等待3");
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
NSLog(@"結(jié)束");
例子中創(chuàng)建了一個初始值為0的信號量和一個并行隊列, 采用異步執(zhí)行裹纳,每個執(zhí)行都有:開始、等待紧武、執(zhí)行剃氧、釋放四步,本例中上一個的釋放與下一個的開始是并行執(zhí)行的阻星,輸出內(nèi)容為:
也可以將本例中初始信號量的值修改為大于0朋鞍,輸出結(jié)果可自行調(diào)試