美文网首页
dispatch_semaphore信号量实现线程同步

dispatch_semaphore信号量实现线程同步

作者: Jean_Lina | 来源:发表于2020-07-06 15:33 被阅读0次
    • GCD 中的信号量是指 Dispatch Semaphore,是持有计数的信号。类似于过高速路收费站的栏杆。可以通过时,打开栏杆,不可以通过时,关闭栏杆。
    • 在 Dispatch Semaphore中,使用计数来完成这个功能,计数为0时等待,不可通过。计数为1或大于1时,计数减1且不等待,可通过。
    • Dispatch Semaphore提供了三个函数:
    1. dispatch_semaphore_create:创建一个Semaphore并初始化信号的总量
    2. dispatch_semaphore_signal:发送一个信号,让信号总量加1
    3. dispatch_semaphore_wait:可以使总信号量减1,当信号总量为0时就会一直等待(阻塞所在线程),否则就可以正常执行。
    #pragma mark dispatch_semaphore信号量
    - (void)gcd_dispatch_semaphore {
        //打印当前线程
        NSLog(@"currentThread---%@",[NSThread currentThread]);
        NSLog(@"semaphore---begin");
        dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
        
        __block NSInteger number = 0;
        dispatch_async(queue, ^{
            // 追加任务1
            //模拟耗时操作
            [NSThread sleepForTimeInterval:2];
            //打印当前线程
            NSLog(@"1---%@",[NSThread currentThread]);
            number = 100;
            dispatch_semaphore_signal(semaphore);
        });
        
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSLog(@"semaphore---end,number = %ld",(long)number);
    }
    
    输出结果:
    2020-07-06 15:28:49.979677+0800 GCD[2989:1190741] currentThread---<NSThread: 0x2804b4f80>{number = 1, name = main}
    2020-07-06 15:28:49.979764+0800 GCD[2989:1190741] semaphore---begin
    2020-07-06 15:28:51.984955+0800 GCD[2989:1190767] 1---<NSThread: 0x28048f400>{number = 3, name = (null)}
    2020-07-06 15:28:51.985111+0800 GCD[2989:1190741] semaphore---end,number = 100
    
    • semaphore---end是在执行完 number = 100;之后才打印的,而且输出结果 number 为 100。
    • 这是因为异步执行不会做任何等待,可以继续执行任务。
    • 异步执行将任务1追加到队列之后,不做等待,接着执行dispatch_semaphore_wait方法。
    • 此时 semaphore == 0,当前线程进入等待状态。然后,异步任务1开始执行。
    • 任务1执行到dispatch_semaphore_signal之后,总信号量,此时 semaphore == 1,dispatch_semaphore_wait方法使总信号量减1,正在被阻塞的线程(主线程)恢复继续执行。
    • 最后打印semaphore---end,number = 100。
    • 这样就实现了线程同步,将异步执行任务转换为同步执行任务。

    相关文章

      网友评论

          本文标题:dispatch_semaphore信号量实现线程同步

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