理解信号量
理解信号量我们必须了解一下三个函数:
-
dispatch_semaphore_create(long value);
创建信号量,参数为设置信号量的初始值 -
dispatch_semaphore_signal(dispatch_semaphore_t dsema);
发送当前信号量,参数为当前创建的信号量 -
dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout);
等待信号量,第一个为当前等待的信号量,第二个参数为超时时间。当等待时间超过超时时间就不会继续等待了。
信号量是一个整型值,在创建的时候会有一个初始值。当执行dispatch_semaphore_signal
发送信号的时候信号量会加1,dispatch_semaphore_wait
在信号量小于或等于0的时候会一直等待,直到超时,并且会阻塞该线程,当信号量大于0时会继续执行并对信号量执行减1操作。
信号量使用
常见使用方法:
- 创建信号量
- 在要执行的任务前设置信号量等待
dispatch_semaphore_wait
- 当其信号量的值大于0时则会执行这个任务,如小于等于0,则会一直等待阻塞当前线程;
- 发送信号量
dispatch_semaphore_signal
设置最大并发线程、多个异步任务执行完再执行下一步
//创建线程组
dispatch_group_t group = dispatch_group_create();
//创建值为10的信号量
dispatch_semaphore_t semaphore = dispatch_semaphore_create(10);
//获取全局并发队列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
for (int i = 0; i < 20; i++) {
//信号量小于等于0时,线程等待
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
dispatch_group_async(group, queue, ^{
NSLog(@"%i",i);
sleep(2);
//发送信号量 信号量值加1
dispatch_semaphore_signal(semaphore);
});
}
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
NSLog(@"do something");
从以上代码可以看到,创建了一个线程组,并在线程组中引入了全局的并发队列,同时创建了值为10的信号量,每次执行dispatch_semaphore_wait
后信号量的值会减1,并且加入一个异步任务到队列中,直到信号量的值小于等于0时会阻塞当前前线程,停止tian任务,直到有任务完成信号量会加1。
多异步任务同步执行
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);
//创建的4个任务执行完之后
NSLog(@"do something");
上面代码我们创建了值为0的信号量,task1、task2、task3三个任务。当信号量执行到task1时只有task1执行完,发送信号量dispatch_semaphore_signal
后才会执行task2。