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

  

 

posted on 2017-09-02 20:43  HJiang  阅读(655)  评论(0编辑  收藏  举报