zoukankan      html  css  js  c++  java
  • GCD使用dispatch_semaphore_t创建多线程网络同步请求

    一、简介:

    dispatch_semaphore_t:表示信号,生成信号的方法是

    dispatch_semaphore_t semaphore= dispatch_semaphore_create(0);

    其中参数0表示该新生成信号的总的信号量为0个。

    dispatch_semaphore_wait:信号等待,它像一个安保,比如小区规定最多只能进入3辆车,而进入一辆车后名额就会减少一个,当剩下的名额为0的时候,再有汽车说要进去时,就只能在外面等待了,直到有名额闲置出来了,才能开进小区。

    dispatch_semaphore_signal:信号释放,当有一辆车从小区出来时,就腾出来了一个名额。

     二、验证

    这三个常用方法解释就暂且到这里,下面用代码来验证下上面介绍的作用。

    pastedGraphic.png

    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{

        [self syncAction1];

    }

    - (void)syncAction1{

        

        //使用GCD的信号量 dispatch_semaphore_t 创建同步请求

        dispatch_group_t group =dispatch_group_create();

        dispatch_queue_t globalQueue=dispatch_get_global_queue(0, 0);

        

        dispatch_group_async(group, globalQueue, ^{

            dispatch_semaphore_t semaphore= dispatch_semaphore_create(0);

            //模拟网络多线程耗时操作

            dispatch_group_async(group, globalQueue, ^{

                sleep(3);

                NSLog(@"%@---block1结束。。。",[NSThread currentThread]);

                dispatch_semaphore_signal(semaphore);

            });

            NSLog(@"%@---1结束。。。",[NSThread currentThread]);

            dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);

        });

        dispatch_group_async(group, globalQueue, ^{

            dispatch_semaphore_t semaphore= dispatch_semaphore_create(0);

            

            //模拟网络多线程耗时操作

            dispatch_group_async(group, globalQueue, ^{

                sleep(3);

                NSLog(@"%@---block2结束。。。",[NSThread currentThread]);

                dispatch_semaphore_signal(semaphore);

            });

            

            NSLog(@"%@---2结束。。。",[NSThread currentThread]);

            dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);

        });

        dispatch_group_notify(group, dispatch_get_global_queue(0, 0), ^{

            NSLog(@"%@---全部结束。。。",[NSThread currentThread]);

            

        });

        

    }

    pastedGraphic.png

    运行APP,点击页面,打印的结果如下:

    pastedGraphic.png

    2016-12-22 23:45:36.633 GCDTest[852:27326] <NSThread: 0x7fce485154f0>{number = 2, name = (null)}---1结束。。。

    2016-12-22 23:45:36.633 GCDTest[852:27328] <NSThread: 0x7fce48606f40>{number = 3, name = (null)}---2结束。。。

    2016-12-22 23:45:39.633 GCDTest[852:27329] <NSThread: 0x7fce48512ea0>{number = 4, name = (null)}---block1结束。。。

    2016-12-22 23:45:39.633 GCDTest[852:27330] <NSThread: 0x7fce484a9960>{number = 5, name = (null)}---block2结束。。。

    2016-12-22 23:45:39.634 GCDTest[852:27328] <NSThread: 0x7fce48606f40>{number = 3, name = (null)}---全部结束。。。

    pastedGraphic.png

    结论:通过打印结果可以验证,

    1.只有当剩余信号总量大于0时线程才能通过dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);方法,继续向下执行。

    2.当dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);下面的代码无法执行处于等待情况下时,dispatch_semaphore_signal(semaphore);一旦执行,释放出自己的信号,则代码又可以愉快的往下执行了。

    dispatch_queue_t queue = dispatch_get_global_queue(0, 0); 

    dispatch_semaphore_t semaphore = dispatch_semaphore_create(1); 

    for (int i = 0; i < 100; i++)

     { 

      dispatch_async(queue, ^{

         // 相当于加锁 

        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); 

          NSLog(@"i = %zd semaphore = %@", i, semaphore); // 相当于解锁 

          dispatch_semaphore_signal(semaphore); 

      }); 

    }

  • 相关阅读:
    vue中的 computed 和 watch 的区别
    mysql8.0 初始化数据库及表名大小写问题
    sql server alwayson 调整数据文件路径
    zabbix 自定义监控 SQL Server
    mysql 创建用户及授权
    mysql 设置从库只读模式
    mysql8.0 主从复制安装及配置
    centos8.0安装mysql8.0
    centos8替换阿里数据源
    npm publish 报错 【you or one of your dependencies are requesting a package version that is forbidden by your security policy】
  • 原文地址:https://www.cnblogs.com/sundaysgarden/p/10371986.html
Copyright © 2011-2022 走看看