美文网首页
浅谈GCD信号量dispatch_semaphore_t

浅谈GCD信号量dispatch_semaphore_t

作者: Devbrave | 来源:发表于2019-12-12 13:08 被阅读0次

理解信号量

理解信号量我们必须了解一下三个函数:

  • dispatch_semaphore_create(long value);创建信号量,参数为设置信号量的初始值
  • dispatch_semaphore_signal(dispatch_semaphore_t dsema);发送当前信号量,参数为当前创建的信号量
  • dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout);等待信号量,第一个为当前等待的信号量,第二个参数为超时时间。当等待时间超过超时时间就不会继续等待了。

信号量是一个整型值,在创建的时候会有一个初始值。当执行dispatch_semaphore_signal发送信号的时候信号量会加1,dispatch_semaphore_wait在信号量小于或等于0的时候会一直等待,直到超时,并且会阻塞该线程,当信号量大于0时会继续执行并对信号量执行减1操作。

信号量使用

常见使用方法:

  1. 创建信号量
  2. 在要执行的任务前设置信号量等待dispatch_semaphore_wait
  3. 当其信号量的值大于0时则会执行这个任务,如小于等于0,则会一直等待阻塞当前线程;
  4. 发送信号量dispatch_semaphore_signal

设置最大并发线程、多个异步任务执行完再执行下一步

    //创建线程组
    dispatch_group_t group = dispatch_group_create();   
    //创建值为10的信号量
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(10);
    //获取全局并发队列
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);   
    for (int i = 0; i < 20; i++) {   
    //信号量小于等于0时,线程等待
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);   
        dispatch_group_async(group, queue, ^{   
            NSLog(@"%i",i);   
            sleep(2);   
            //发送信号量 信号量值加1
            dispatch_semaphore_signal(semaphore);   
        });   
    }
    dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
    NSLog(@"do something");

从以上代码可以看到,创建了一个线程组,并在线程组中引入了全局的并发队列,同时创建了值为10的信号量,每次执行dispatch_semaphore_wait后信号量的值会减1,并且加入一个异步任务到队列中,直到信号量的值小于等于0时会阻塞当前前线程,停止tian任务,直到有任务完成信号量会加1。

多异步任务同步执行

   dispatch_semaphore_t sem = dispatch_semaphore_create(0);
    dispatch_queue_t quene = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(quene, ^{
        sleep(1);
        NSLog(@"task 1");
        dispatch_semaphore_signal(sem);
    });
    dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
    
    dispatch_async(quene, ^{
        sleep(1);
        NSLog(@"task 2");
        dispatch_semaphore_signal(sem);
    });
    dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);

    
    dispatch_async(quene, ^{
        sleep(1);
        NSLog(@"task 3");
        dispatch_semaphore_signal(sem);
    });

    dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
    //创建的4个任务执行完之后
    NSLog(@"do something");

上面代码我们创建了值为0的信号量,task1、task2、task3三个任务。当信号量执行到task1时只有task1执行完,发送信号量dispatch_semaphore_signal后才会执行task2。

相关文章

网友评论

      本文标题:浅谈GCD信号量dispatch_semaphore_t

      本文链接:https://www.haomeiwen.com/subject/vnttnctx.html