1、使用场景:
当下载多个图片时,并发异步,每个下载都开辟一条线程的话,cpu会吃不消,这时候就可以用信号量来控制一下开辟线程的最大数,避免同时开太多的线程,总体来说,信号量起到的就是这个作用。
2、相关函数
第一个:dispatch_semaphore_create
创建信号量的函数 dispatch_semaphore_t dispatch_semaphore_create(long value);
传入的参数为long,输出一个dispatch_semaphore_t类型且值为value的信号量。那这个传入的参数的值应该代表的就是能同时开辟的最大线程数了。
值得注意的是,这里的传入的参数value必须大于或等于0,否则dispatch_semaphore_create会返回NULL。
第二个:dispatch_semaphore_wait
long dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout);
第一个参数传的是信号量,也就是用第一个函数创建的,第二个参数传的是等待的时间,一般会传DISPATCH_TIME_FOREVER,也就是一直等待。
这个函数的作用是先判断传入的信号量值是否大于0,,如果大于0,将信号量的值减1,执行后面的代码。如果信号量的值等于0,说明现在运行的线程已经达到最大数了,只能等待,等待的时间就是timeout的值,如果在等待的期间,信号量的值增加了1,就自定执行后面的代码,并将信号量减1,这时候该函数的返回值会返回0;如果等待期间信号量一直为0,等到timeout之后,会执行后面的代码,这时候该函数的返回值不等于0。
第三个函数:dispatch_semaphore_signal(信号量)
long dispatch_semaphore_signal(dispatch_semaphore_t dsema)
这个函数是将信号量的值加1,也就是告诉正在等待的线程,我执行完了,你可以执行你的代码了。
该函数的返回值是long型,当返回值大于0时,表示当前有线程正在等待,反之则没有。
使用顺序:先调用第二个函数,再调用第三个函数
3、代码使用
dispatch_semaphore_t semaphore = dispatch_semaphore_create(2);
dispatch_queue_t quene = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//任务1
dispatch_async(quene, ^{
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
NSLog(@"run task 1");
sleep(1);
NSLog(@"complete task 1");
dispatch_semaphore_signal(semaphore);
});
//任务2
dispatch_async(quene, ^{
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
NSLog(@"run task 2");
sleep(1);
NSLog(@"complete task 2");
dispatch_semaphore_signal(semaphore);
});
//任务3
dispatch_async(quene, ^{
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
NSLog(@"run task 3");
sleep(1);
NSLog(@"complete task 3");
dispatch_semaphore_signal(semaphore);
});