GCD中, 有一些函數(shù)很常用, 比如同步函數(shù), 異步函數(shù), 障礙函數(shù), 一次性函數(shù)等; 另外一些不太常用, 如迭代函數(shù)(dispatch_apply), 還有就是今天要說的信號量函數(shù).
今天不打算介紹其他函數(shù), 只說信號量函數(shù).
<br />
- 首先, 什么是信號量? 它有什么用?
以一個(gè)停車場的運(yùn)作為例:
簡單起見窿侈,假設(shè)停車場只有三個(gè)車位炼幔,一開始三個(gè)車位都是空的。
這時(shí)如果同時(shí)來了五輛車史简,看門人允許其中三輛直接進(jìn)入乃秀,然后放下車攔,剩下的車則必須在入口等待圆兵,此后來的車也都不得不在入口處等待跺讯。這時(shí),有一輛車離開停車場殉农,看門人得知后刀脏,打開車攔,放入外面的一輛進(jìn)去统抬,如果又離開兩輛火本,則又可以放入兩輛危队,如此往復(fù)聪建。
在這個(gè)停車場系統(tǒng)中,車位是公共資源茫陆,每輛車好比一個(gè)線程金麸,看門人起的就是信號量的作用。
從這段描述我們可以看出, 信號量的作用和互斥鎖差不多, 都是保證線程安全的手段.
<br />
- 那么, 信號量函數(shù)有哪些? 怎么用?
在GCD中, 有三個(gè)函數(shù)是semaphore的操作簿盅,
分別是:
- dispatch_semaphore_create()
作用: 創(chuàng)建一個(gè)semaphore函數(shù), 并設(shè)置信號量總數(shù).
參數(shù): 需要傳入一個(gè)long int的參數(shù), 這個(gè)參數(shù)就是信號量總數(shù).
返回值: 返回一個(gè)dispatch_semaphore_t類型的信號量對象.
- dispatch_semaphore_signal()
作用: 發(fā)送一個(gè)信號. 相當(dāng)于給信號量+1.
參數(shù): 需要傳入一個(gè)信號量對象, 來確定操作哪個(gè)信號量函數(shù). - dispatch_semaphore_wait()
作用: 等待信號 . 執(zhí)行到這里的時(shí)候, 如果發(fā)現(xiàn)信號量>0, 那么它后面的語句就正常執(zhí)行, 同時(shí)它會給信號量-1; 如果發(fā)現(xiàn)信號量<=0, 那么就會一直阻塞在這里, 它后面的語句都不能執(zhí)行, 直到信號量>0, 才能過掉這個(gè)函數(shù).
參數(shù): 需要傳入一個(gè)信號量對象, 來確定操作哪個(gè)信號量函數(shù).
從這段描述我們可以看出, 信號量函數(shù)有點(diǎn)類似于障礙函數(shù), 兩者都是阻塞型函數(shù).
<br />
- 廢話不多說, 直接上代碼!
示例代碼:
//創(chuàng)建一個(gè)信號量為0的semaphore函數(shù). 因?yàn)橐赽lock里用這個(gè)函數(shù), 記得前面要加上__block.
__block dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
//創(chuàng)建一個(gè)并發(fā)隊(duì)列
dispatch_queue_t queue = dispatch_queue_create("StudyBlocks", NULL);
//異步執(zhí)行
dispatch_async(queue, ^(void)
{
for (int i = 0; i < 5; i ++)
{
NSLog(@">> i: %d", i);
}
dispatch_semaphore_signal(semaphore);
});
//雖然是并發(fā)隊(duì)列+異步函數(shù), 但執(zhí)行到wait的時(shí)候, 發(fā)現(xiàn)信號量為0, 所以會阻塞在這里. 直到異步函數(shù)里的for循環(huán)執(zhí)行完畢, 然后dispatch_semaphore_signal(semaphore)函數(shù)將信號量+1, 才會執(zhí)行wait后面的for循環(huán).
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
for (int j = 0; j < 5; j ++)
{
NSLog(@">> Main Data: %d", j);
}
運(yùn)行結(jié)果:
test[15518:632061] >> i: 0
test[15518:632061] >> i: 1
test[15518:632061] >> i: 2
test[15518:632061] >> i: 3
test[15518:632061] >> i: 4
test[15518:632036] >> Main Data: 0
test[15518:632036] >> Main Data: 1
test[15518:632036] >> Main Data: 2
test[15518:632036] >> Main Data: 3
test[15518:632036] >> Main Data: 4