iOS中使用GCD配合信号量做任务管理
2019-10-16 本文已影响0人
GoldenChan
什么是信号量?
信号量是一种线程阻塞操作,通过对信号量的设置可以限制同时执行任务的数量。
相关方法执行原理?
1、//创建信号量,参数:信号量的初值,如果小于0则会返回NULL
dispatch_semaphore_create(信号量值)
2、//等待降低信号量(这里对信号量执行-1操作,当结果小于0时,阻塞,不小于0时继续往下执行)
dispatch_semaphore_wait(信号量,等待时间)
3、//提高信号量(这里对信号量执行+1操作)
dispatch_semaphore_signal(信号量)
什么时候会用到信号量?
场景1.比如做下载任务时,需要限制同时下载的任务数
场景2.比如异步执行多个任务,但又想让每个任务按一定的顺序执行时
//场景1,设置同时下载任务数为5
dispatch_queue_t queue = dispatch_queue_create("queuename", DISPATCH_QUEUE_CONCURRENT);
//初始化信号量
dispatch_semaphore_t semaphore = dispatch_semaphore_create(5);
for (int i = 0 ; i<10; i++) {
//执行-1操作,并判断是否开始等待
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
dispatch_async(queue, ^{
//模拟下载任务
NSLog(@"%i开始下载",i);
sleep(10+i*2);//假设下载一集需要10+i*2秒
NSLog(@"%i下载完成",i);
dispatch_semaphore_signal(semaphore);
});
}
NSLog(@"执行完毕");
//打印结果
2开始下载
1开始下载
3开始下载
0开始下载
4开始下载
0下载完成
5开始下载
1下载完成
6开始下载
2下载完成
7开始下载
3下载完成
8开始下载
4下载完成
执行完毕
9开始下载
5下载完成
6下载完成
7下载完成
8下载完成
9下载完成
//注:这里打印结果看出,并不是所有下载都会执行完才会打印执行完毕,因为这里的wait只是阻塞了for循环,在执行最后的等于或小于5个的任务数时,是异步执行,所以会先执行 NSLog(@"执行完毕");
//场景2,使每个任务按照循环顺序执行
dispatch_queue_t queue = dispatch_queue_create("queuename", DISPATCH_QUEUE_CONCURRENT);
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
for (int i = 0 ; i<10; i++) {
dispatch_async(queue, ^{
//模拟下载任务
NSLog(@"执行任务%i",i);
dispatch_semaphore_signal(semaphore);
});
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
}
NSLog(@"执行完毕");
//打印结果
执行任务0
执行任务1
执行任务2
执行任务3
执行任务4
执行任务5
执行任务6
执行任务7
执行任务8
执行任务9
执行完毕