GCD信号量semaphore控制线程并发数

GCD提供了信号semaphore来控制线程并发数,提供一下三个函数

dispatch_semaphore_create(<#long value#>) // 创建信号semaphore,value参数为任务并发同时执行时线程最大并发数

dispatch_semaphore_wait(<#dispatch_semaphore_t  _Nonnull dsema#>, <#dispatch_time_t timeout#>) // 信号阻塞,信号发送后->判断是否有空闲的计数可用,如果有可用计数执行后面的任务,如果没有可用计数就让当前线程阻塞

dispatch_semaphore_signal(<#dispatch_semaphore_t  _Nonnull dsema#>) // 信号发送,信号发送后->通知有空闲的计数可用,其他阻塞的任务就可以执行

 

    dispatch_semaphore_t semaphore = dispatch_semaphore_create(2);
    
    dispatch_group_t group = dispatch_group_create();
    
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    for (int i=0; i<20; i++) {  // for 20次,每次创建一个线程执行任务,当线程任务达到2个后,创建任务就会被阻塞,至到有任务完成并signal后,wait等待线程才会解除阻塞,继续被执行
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        dispatch_group_async(group, queue, ^{
            NSLog(@"%zd ---%@",i,[NSThread currentThread]);
            [NSThread sleepForTimeInterval:0.2];
            dispatch_semaphore_signal(semaphore);
        });
    }
    
    dispatch_group_wait(group, 4); // group任务等待4秒,如果group所有任务任务4秒还未执行完成,执行下面任务
    
    dispatch_group_notify(group, queue, ^{
        NSLog(@"dispatch_group_notify"); // group内任务全部执行完毕,通知回调
    });
    
    NSLog(@"semaphore end...");
    
    2017-09-02 20:31:53.611 GCD测试[16021:328482] 0 ---<NSThread: 0x600000275780>{number = 7, name = (null)}
    2017-09-02 20:31:53.611 GCD测试[16021:329153] 1 ---<NSThread: 0x608000263b40>{number = 10, name = (null)}
    2017-09-02 20:31:53.885 GCD测试[16021:328482] 2 ---<NSThread: 0x600000275780>{number = 7, name = (null)}
    2017-09-02 20:31:53.885 GCD测试[16021:329153] 3 ---<NSThread: 0x608000263b40>{number = 10, name = (null)}
    2017-09-02 20:31:54.152 GCD测试[16021:328482] 4 ---<NSThread: 0x600000275780>{number = 7, name = (null)}
    2017-09-02 20:31:54.152 GCD测试[16021:329153] 5 ---<NSThread: 0x608000263b40>{number = 10, name = (null)}
    2017-09-02 20:31:54.400 GCD测试[16021:329153] 6 ---<NSThread: 0x608000263b40>{number = 10, name = (null)}
    2017-09-02 20:31:54.400 GCD测试[16021:328482] 7 ---<NSThread: 0x600000275780>{number = 7, name = (null)}
    2017-09-02 20:31:54.601 GCD测试[16021:329153] 8 ---<NSThread: 0x608000263b40>{number = 10, name = (null)}
    2017-09-02 20:31:54.601 GCD测试[16021:328482] 9 ---<NSThread: 0x600000275780>{number = 7, name = (null)}
    2017-09-02 20:31:54.801 GCD测试[16021:329153] 10 ---<NSThread: 0x608000263b40>{number = 10, name = (null)}
    2017-09-02 20:31:54.801 GCD测试[16021:328482] 11 ---<NSThread: 0x600000275780>{number = 7, name = (null)}
    2017-09-02 20:31:55.069 GCD测试[16021:329153] 13 ---<NSThread: 0x608000263b40>{number = 10, name = (null)}
    2017-09-02 20:31:55.069 GCD测试[16021:328482] 12 ---<NSThread: 0x600000275780>{number = 7, name = (null)}
    2017-09-02 20:31:55.270 GCD测试[16021:328482] 14 ---<NSThread: 0x600000275780>{number = 7, name = (null)}
    2017-09-02 20:31:55.270 GCD测试[16021:329153] 15 ---<NSThread: 0x608000263b40>{number = 10, name = (null)}
    2017-09-02 20:31:55.470 GCD测试[16021:329153] 17 ---<NSThread: 0x608000263b40>{number = 10, name = (null)}
    2017-09-02 20:31:55.470 GCD测试[16021:328482] 16 ---<NSThread: 0x600000275780>{number = 7, name = (null)}
    2017-09-02 20:31:55.711 GCD测试[16021:328215] semaphore end...
    2017-09-02 20:31:55.711 GCD测试[16021:328482] 18 ---<NSThread: 0x600000275780>{number = 7, name = (null)}
    2017-09-02 20:31:55.711 GCD测试[16021:329153] 19 ---<NSThread: 0x608000263b40>{number = 10, name = (null)}
    2017-09-02 20:31:55.912 GCD测试[16021:329153] dispatch_group_notify

经测试信号量设置为2,但是任务开启的任务线程有时可能为3个,这个不是说信号量不起作用,3表示并发线程2个,但是线程使用完后,下次2个同时并发时可能会开启新的线程,也有可能直接使用上次并发完的线程

 

示例:

 

__block BOOL isok = NO;

dispatch_semaphore_t sema = dispatch_semaphore_create(0);
EventEngine *engine = [[EventEngine alloc] init];
[engine engineCompletion:^(BOOL isOpen) {
    isok = isOpen;
    dispatch_semaphore_signal(sema);
} onError:^(int errorCode, NSString *errorMessage) {
    isok = NO;
    dispatch_semaphore_signal(sema);
}];

dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
// 等待engine有结果后才解除阻塞

// do other task

  

 

转载于:https://www.cnblogs.com/HJiang/p/7467752.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值