dispatch_semaphore_create(1)
創(chuàng)建一個 semaphore
信號總量為 1
dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER)
如果信號總量為0,進(jìn)入等待狀態(tài)珊皿,信號量大于0時歼捐,繼續(xù)執(zhí)行代碼,同時將信號總量 -1
dispatch_semaphore_signal(lock);
發(fā)送信號量币喧,信號量 +1
使用時注意使用
signal
以確保編譯器release
掉dispatch_semaphore_t
時的值與初始值一致, 否則會EXC_BAD_INSTRUCTION
,見http://is.gd/EaJgk5
dispatch_semaphore_t lock = dispatch_semaphore_create(1);
for (int i = 0; i < 10; i++)
{
dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER);
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"%d", i);
dispatch_semaphore_signal(lock);
});
}
獲取通訊錄
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
ABAddressBookRequestAccessWithCompletion(abRef, ^(bool granted, CFErrorRef error)
{
isOpen = granted;
dispatch_semaphore_signal(sema);
});
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
CFRelease(abRef);
?
使用 Dispatch Semaphore 控制并發(fā)線程數(shù)量
void dispatch_async_limit(dispatch_queue_t queue,NSUInteger limitSemaphoreCount, dispatch_block_t block) {
//控制并發(fā)數(shù)的信號量
static dispatch_semaphore_t limitSemaphore;
//專門控制并發(fā)等待的線程
static dispatch_queue_t receiverQueue;
//使用 dispatch_once而非 lazy 模式,防止可能的多線程搶占問題
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
limitSemaphore = dispatch_semaphore_create(limitSemaphoreCount);
receiverQueue = dispatch_queue_create("receiver", DISPATCH_QUEUE_SERIAL);
});
// 如不加 receiverQueue 放在主線程會阻塞主線程
dispatch_async(receiverQueue, ^{
//可用信號量后才能繼續(xù),否則等待
dispatch_semaphore_wait(limitSemaphore, DISPATCH_TIME_FOREVER);
dispatch_async(queue, ^{
!block ? : block();
//在該工作線程執(zhí)行完成后釋放信號量
dispatch_semaphore_signal(limitSemaphore);
});
});
}
??????
?????????????