理解信號(hào)量
理解信號(hào)量我們必須了解一下三個(gè)函數(shù):
-
dispatch_semaphore_create(long value);創(chuàng)建信號(hào)量,參數(shù)為設(shè)置信號(hào)量的初始值 -
dispatch_semaphore_signal(dispatch_semaphore_t dsema);發(fā)送當(dāng)前信號(hào)量,參數(shù)為當(dāng)前創(chuàng)建的信號(hào)量 -
dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout);等待信號(hào)量,第一個(gè)為當(dāng)前等待的信號(hào)量,第二個(gè)參數(shù)為超時(shí)時(shí)間。當(dāng)?shù)却龝r(shí)間超過(guò)超時(shí)時(shí)間就不會(huì)繼續(xù)等待了。
信號(hào)量是一個(gè)整型值,在創(chuàng)建的時(shí)候會(huì)有一個(gè)初始值。當(dāng)執(zhí)行dispatch_semaphore_signal發(fā)送信號(hào)的時(shí)候信號(hào)量會(huì)加1,dispatch_semaphore_wait在信號(hào)量小于或等于0的時(shí)候會(huì)一直等待,直到超時(shí),并且會(huì)阻塞該線程,當(dāng)信號(hào)量大于0時(shí)會(huì)繼續(xù)執(zhí)行并對(duì)信號(hào)量執(zhí)行減1操作。
信號(hào)量使用
常見(jiàn)使用方法:
- 創(chuàng)建信號(hào)量
- 在要執(zhí)行的任務(wù)前設(shè)置信號(hào)量等待
dispatch_semaphore_wait - 當(dāng)其信號(hào)量的值大于0時(shí)則會(huì)執(zhí)行這個(gè)任務(wù),如小于等于0,則會(huì)一直等待阻塞當(dāng)前線程;
- 發(fā)送信號(hào)量
dispatch_semaphore_signal
設(shè)置最大并發(fā)線程、多個(gè)異步任務(wù)執(zhí)行完再執(zhí)行下一步
//創(chuàng)建線程組
dispatch_group_t group = dispatch_group_create();
//創(chuàng)建值為10的信號(hào)量
dispatch_semaphore_t semaphore = dispatch_semaphore_create(10);
//獲取全局并發(fā)隊(duì)列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
for (int i = 0; i < 20; i++) {
//信號(hào)量小于等于0時(shí),線程等待
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
dispatch_group_async(group, queue, ^{
NSLog(@"%i",i);
sleep(2);
//發(fā)送信號(hào)量 信號(hào)量值加1
dispatch_semaphore_signal(semaphore);
});
}
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
NSLog(@"do something");
從以上代碼可以看到,創(chuàng)建了一個(gè)線程組,并在線程組中引入了全局的并發(fā)隊(duì)列,同時(shí)創(chuàng)建了值為10的信號(hào)量,每次執(zhí)行dispatch_semaphore_wait后信號(hào)量的值會(huì)減1,并且加入一個(gè)異步任務(wù)到隊(duì)列中,直到信號(hào)量的值小于等于0時(shí)會(huì)阻塞當(dāng)前前線程,停止tian任務(wù),直到有任務(wù)完成信號(hào)量會(huì)加1。
多異步任務(wù)同步執(zhí)行
dispatch_semaphore_t sem = dispatch_semaphore_create(0);
dispatch_queue_t quene = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(quene, ^{
sleep(1);
NSLog(@"task 1");
dispatch_semaphore_signal(sem);
});
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
dispatch_async(quene, ^{
sleep(1);
NSLog(@"task 2");
dispatch_semaphore_signal(sem);
});
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
dispatch_async(quene, ^{
sleep(1);
NSLog(@"task 3");
dispatch_semaphore_signal(sem);
});
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
//創(chuàng)建的4個(gè)任務(wù)執(zhí)行完之后
NSLog(@"do something");
上面代碼我們創(chuàng)建了值為0的信號(hào)量,task1、task2、task3三個(gè)任務(wù)。當(dāng)信號(hào)量執(zhí)行到task1時(shí)只有task1執(zhí)行完,發(fā)送信號(hào)量dispatch_semaphore_signal后才會(huì)執(zhí)行task2。