-
dispatch_semaphore的主要作用 :
-
保持线程同步
-
为线程加锁
-
主要方法:
-
dispatch_semaphore_t dispatch_semaphore_create(long value)
:方法接收一个long类型的参数, 返回参数中dispatch_semaphore_t类型的信号总量 -
long dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout)
:接收一个信号和时间值,若信号的信号量为0,则会阻塞当前线程,直到信号量大于0或者经过输入的时间值;若信号量大于0,则会使信号量减1并返回,程序继续住下执行 -
long dispatch_semaphore_signal(dispatch_semaphore_t dsema)
:使信号量加1并返回
// 以打印100个数字为例
for (int i = 0; i < 100; i ++) {
NSLog(@"%i", i);
}
上述打印后会在控制台中依次输出1-100
- 用
dispatch_semaphore
让线程加锁
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);
for (int i = 0; i < 100; i++) {
dispatch_async(queue, ^{
// 相当于加锁
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
NSLog(@"i = %zd semaphore = %@", i, semaphore);
NSLog(@"%d", i);
// 相当于解锁
dispatch_semaphore_signal(semaphore);
});
}
分析:以上代码首先创建一个队列,随后异步运行队列,没有加dispatch_semaphore
之前控制台打印的数据顺序不一,加上dispatch_semaphore
之后,会发现顺序变一致了。因为加锁进入
dispatch_semaphore_wait
的时候,信号量便会0,阻塞当前的线程,异步进入此命令的时候,无法继续执行下一步,随后到达dispatch_semaphore_signal
,信号量+1,此时线程通常,如此便可以为线程加锁。
- 用dispatch_semaphore 每隔10秒打印顺序不一的数字。
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_group_t group = dispatch_group_create();
dispatch_semaphore_t semaphore = dispatch_semaphore_create(10);
for (int i = 0; i < 100; i ++) {
dispatch_group_async(group, queue, ^{
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
NSLog(@"%d",i);
sleep(2);
dispatch_semaphore_signal(semaphore);
});
}
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
分析: 信号量为10,并发进入dispatch_semaphore_wait的时候,递减到0, 随后线程堵塞,sleep(2)中阻塞当前线程直到两秒后dispatch_semaphore_signal依次递增,并返回信号量,这样就可以每隔10秒打印顺序不一的数字。
dispatch_group_wait
会一直阻塞线程,直到 dispatch_group_t完成或者超时才会执行以下的代码。
网友评论