GCD(Dispatch Semaphore)
Dispatch Semaphore 是持有计数的信号,该计数是多线程编写中的计数类型信号。在 Dispatch Semaphore中,使用计数来实现该功能。计数为0时等待,计数为1或大于1时而不等待。
1.创建新的计数Semaphore的初始值。
dispatch_semaphore_t dispatch_semaphore_create( long value);
从函数名称中含有的 create 可以看出,该函数与 Dispatch Queue 和 Dispatch Group一样,必须通过 dispatch_release 函数释放。
2.等待(减少)一个信号量
long dispatch_semaphore_wait( dispatch_semaphore_t dsema, dispatch_time_t timeout);
dispatch_semaphore_wait 函数等待 Dispatch Semaphore的计数值达到大于或等于1.当计数值大于等于1,或者在待机中计数值大于等于1时,对该计数进行减法并从函数返回。另外,dispatch_semaphore_wait 函数的返回值也可以进行分支处理。
dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW,1ull * NSEC_PER_SEC);
long result = dispatch_semaphore_wait(semaphore,time);
if(result == 0){
/**
* 由于 Dispatch Semaphore 的计数值达到大于等于1,
* 或者在待机的指定时间内,Dispatch Semaphore 的计数值达到大于等于1.
* 可执行需要进行排他控制的处理。
*/
} else {
/** 由于 Dispatch Semaphore 的计数值为0,因此在达到指定时间为止待机 */
}
3.信号的信号量(增量)
long dispatch_semaphore_signal( dispatch_semaphore_t dsema);
dispatch_semaphore_wait 函数返回0时,可安全地执行需要排他控制的处理。该处理结束时通过 dispatch_semaphore_signal 函数将 Dispatch Semaphore 的计数值加1.
来一波代码~
dispatch_queue_t queue =
dispatch_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
/**
* 生成 Dispatch Semaphore, 计数初始值为“1”。
* 保证可访问 NSMutableArray 类对象的线程同时只能有1个。
*/
dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);
NSMutableArray *array = [NSMutableArray alloc]init];
for(int i = 0;i < 10000;i++){
dispatch_async(queue,^{
/*
* 等待 Dispatch Semaphore,一直等待,直到计数值达到大于等于1.
*/
dispatch_semaphore_wait(semaphore,DISPATCH_TIME_FOREVER);
/*
* 由于 Dispatch Semaphore 的计数值大于等于1,
* 所以将 Dispatch Semaphore 的计数值减去1,
* dispatch_semaphore_wait 函数执行返回。
* 即执行到此时的 Dispatch Semaphore 的计数值恒为“0”。
* 由于可访问 NSMutableArray 类对象的线程只有1个,
* 因此可以安全地进行更新。
*/
[array add object:[NSNumber numberwithInt:i]];
/*
* 排他控制处理结束,
* 所以通过 dispatch_semaphore_signal 函数将 Dispatch Semaphore 的计数加1.
*
* 如果有通过 dispatch_semaphore_wait 函数等待
* Dispatch Semaphore 的计数值增加的线程,
* 就由最先等待的线程执行。
*/
dispatch_semaphore_signal(semaphore);
});
}
/** 释放 */
dispatch_release(semaphore);