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
执行完毕
上一篇下一篇

猜你喜欢

热点阅读