zoukankan      html  css  js  c++  java
  • ios开发GCD(2)-dispatch_semaphore_t信号量计数器

    思考:现在有多个线程异步执行,我们想要同时最多只能执行2个或n个,该怎么办?

    dispatch_semaphore_t

    看代码解析:

        NSLog(@"开始");
        dispatch_semaphore_t t = dispatch_semaphore_create(2);//设置信号量初始值
        
        dispatch_async(dispatch_queue_create("one", DISPATCH_QUEUE_CONCURRENT), ^{
            dispatch_semaphore_wait(t, DISPATCH_TIME_FOREVER);//只有信号量>0时,才执行后面的代码,信号量-1;否则,处于等待状态。
            
            //要执行的操作
            NSLog(@"任务1=%@",[NSThread currentThread]);
            sleep(5);
    
            dispatch_semaphore_signal(t);//任务完成,信号量+1
        });
        
        dispatch_async(dispatch_queue_create("two", DISPATCH_QUEUE_CONCURRENT), ^{
            dispatch_semaphore_wait(t, DISPATCH_TIME_FOREVER);//只有信号量>0时,才执行后面的代码,信号量-1;否则,处于等待状态。
            
            //要执行的操作
            NSLog(@"任务2=%@",[NSThread currentThread]);
           sleep(5);
            
            dispatch_semaphore_signal(t);//任务完成,信号量+1
        });
        
        dispatch_async(dispatch_queue_create("three", DISPATCH_QUEUE_CONCURRENT), ^{
            dispatch_semaphore_wait(t, DISPATCH_TIME_FOREVER);//只有信号量>0时,才执行后面的代码,信号量-1;否则,处于等待状态。
            
            //要执行的操作
            NSLog(@"任务3=%@",[NSThread currentThread]);
            dispatch_semaphore_signal(t);//任务完成,信号量+1
        });
        
        dispatch_async(dispatch_queue_create("four", DISPATCH_QUEUE_CONCURRENT), ^{
            dispatch_semaphore_wait(t, DISPATCH_TIME_FOREVER);//只有信号量>0时,才执行后面的代码,信号量-1;否则,处于等待状态。
            
            //要执行的操作
            NSLog(@"任务4=%@",[NSThread currentThread]);
            dispatch_semaphore_signal(t);//任务完成,信号量+1
        });

    看打印结果:

    2018-10-16 14:05:48.148321+0800 NSThread-GCD-NSOperation[5280:2575154] 开始
    2018-10-16 14:05:48.150346+0800 NSThread-GCD-NSOperation[5280:2575369] 任务1=<NSThread: 0x1c0279a40>{number = 3, name = (null)}
    2018-10-16 14:05:48.150867+0800 NSThread-GCD-NSOperation[5280:2575278] 任务2=<NSThread: 0x1c447ee00>{number = 4, name = (null)}
    2018-10-16 14:05:53.152640+0800 NSThread-GCD-NSOperation[5280:2575371] 任务3=<NSThread: 0x1c046bd00>{number = 5, name = (null)}
    2018-10-16 14:05:53.152729+0800 NSThread-GCD-NSOperation[5280:2575372] 任务4=<NSThread: 0x1c4476440>{number = 6, name = (null)}

    解析:

    这里有4个线程异步执行,正常情况下,是同时执行的,不分先后;

    这里将信号量设为2,说明同时只能执行2个任务。

    代码执行到任务1,信号量-1,这时信号量=1;因为我们设置的同时可以执行2个任务,所以任务2此时也可以执行,代码执行到任务2时,信号量继续-1,此时信号量=0;因为前两个任务都是耗时操作,任务不完成,导致信号量不释放出来(+1),所以后面的异步线程不会执行;只有当前面的有任务完成,信号量+1,这时监测到信号量>0,才会执行后面的任务。

    由打印结果可以看到,任务3和4打印时间比任务1和2迟了5秒。

  • 相关阅读:
    5.11-上位机重新编程
    3.30-计算机系统互联方案
    3.25-两个操作者的通信模式
    3.23-重新定义操作者框架
    go 修改数组中对象的值不生效的解决方法
    go orm QueryTable Filter 不生效解决方法
    Beego orm.Install() 插入 [单条记录] 或 [一批记录],及出现异常 Handler crashed with error <Ormer> table: `.` not found, make sure it was registered with `RegisterModel()`
    go json 序列号、反序列号和数据类型转换
    go json 转换忽略字段、控制字段可有可无
    Flutter 使用 flutter_inappbrowser 加载 H5 及与 js 交互,Methods marked with @UiThread must be executed on the main thread . Current thread: JavaBridge
  • 原文地址:https://www.cnblogs.com/lfyDragon/p/9797783.html
Copyright © 2011-2022 走看看