在前面GCD之信号量机制一中介绍了通过信号量设置并行最大线程数,依此信号量还可以防止多线程访问公有变量时数据有误,下面的代码能说明。

1.下面是不采用信号量修改公有变量的值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
dispatch_group_t group=dispatch_group_create();
//    dispatch_semaphore_t semaphore=dispatch_semaphore_create(1);
    dispatch_queue_t queue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    __block int count=1000;
    for (int i=0; i<100; i++) {
        //信号量减1,如果同时开启10个以上的线程,则信号量小于等于0,此时就会阻塞该线程。
//        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        dispatch_group_async(group, queue, ^{
            int value = (arc4random() % 4) + 6;
            NSLog(@"%d-%d= %d",count,value,count-value);
            count=count-value;
        //每个线程执行减1后通过信号量通知加1,这样始终保持线程在10个之内
//        dispatch_semaphore_signal(semaphore);
        });
    }
     
    dispatch_group_wait(group, DISPATCH_TIME_FOREVER);

2.运行结果如下:

3.声明一个初始值为1的信号量来开启线程修改公有变量时

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
dispatch_group_t group=dispatch_group_create();
   dispatch_semaphore_t semaphore=dispatch_semaphore_create(1);
   dispatch_queue_t queue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
   __block int count=1000;
   for (int i=0; i<100; i++) {
       //信号量减1,如果同时开启10个以上的线程,则信号量小于等于0,此时就会阻塞该线程。
       dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
       dispatch_group_async(group, queue, ^{
           int value = (arc4random() % 4) + 6;
           NSLog(@"%d-%d= %d",count,value,count-value);
           count=count-value;
       //每个线程执行减1后通过信号量通知加1,这样始终保持线程在10个之内
       dispatch_semaphore_signal(semaphore);
       });
   }
    
   dispatch_group_wait(group, DISPATCH_TIME_FOREVER);

4.运行结果如下:

可以看到,第一代码段时修改公有变量时不是有序的,第二个代码段才是真正正确的修改顺序。这过程可取款的过程一样,金额是1000,可能在不同的地方同时取款,取款时不可能金额是像第一代码段那样。这个和C#的lock关键字有一样的效果。

GCD之信号量机制二的更多相关文章

  1. GCD之信号量机制一

    在使用NSOperationQueue进行多线程编程时,可通过[queue setMaxConcurrentOperationCount:5]来设置线程池中最多并行的线程数,在GCD中信号量机制也和它 ...

  2. 【转】进程同步之信号量机制(pv操作)及三个经典同步问题

    原文地址:http://blog.csdn.net/speedme/article/details/17597373 上篇博客中(进程同步之临界区域问题及Peterson算法),我们对临界区,临界资源 ...

  3. 【原创】Linux信号量机制分析

    背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: Kernel版本: ...

  4. Solr4.8.0源码分析(19)之缓存机制(二)

    Solr4.8.0源码分析(19)之缓存机制(二) 前文<Solr4.8.0源码分析(18)之缓存机制(一)>介绍了Solr缓存的生命周期,重点介绍了Solr缓存的warn过程.本节将更深 ...

  5. 锁机制(Lock) 信号量机制(Semaphore) 事件机制(Event)

    IPC  进程间通信(inter-Process Communicate) 锁机制(Lock) l = Lock() 开启一个锁机制(实例化)   一把锁配一个钥匙 l.acquire()  获得钥匙 ...

  6. js的事件机制二

    js的事件机制二 1.给合适的HTML标签添加合适的事件 onchange-----select下拉框 onload-----body标签 单双击-----用户会进行点击动作的HTML元素 鼠标事件 ...

  7. Linux高级调试与优化——信号量机制与应用程序崩溃

    背景介绍 Linux分为内核态和用户态,用户态通过系统调用(syscall)进入内核态执行. 用户空间的glibc库将Linux内核系统调用封装成GNU C Library库文件(兼容ANSI &am ...

  8. C语言使用信号量机制实例:

    C语言使用信号量机制实例: #include <signal.h> #include <unistd.h> #include <stdio.h> #include ...

  9. Linux同步机制(二) - 条件变量,信号量,文件锁,栅栏

    1 条件变量 条件变量是一种同步机制,允许线程挂起,直到共享数据上的某些条件得到满足. 1.1 相关函数 #include <pthread.h>  pthread_cond_t cond ...

随机推荐

  1. windows10企业版怎么关闭自动更新

    windows10企业版怎么关闭自动更新..  我之所以选择关闭自动的更新的原因: 1.Windows版本是激活版的不是注册版的<其实我想说的是我用的是盗版的> 2.对于为什么禁止[系统更 ...

  2. mySQl数据库的学习笔记

    mySQl数据库的学习笔记... ------------------ Dos命令--先在记事本中写.然后再粘贴到Dos中去 -------------------------------- mySQ ...

  3. 没有基础如何学习web渗透测试?

    如果只是因为感兴趣玩玩的话,你可以不需要学习太多的脚本程序. 但是以下条件要具备 1.能看懂教程:能理解原理,例如解析漏洞,sql注入逻辑等 2.前端代码审计:html js css 3.主流工具的使 ...

  4. multisim&proteus&protel比较

    Multisim有超强板级的模拟/数字电路板的设计工作.它包含了电路原理图的图形输入.电路硬件描述语言输入方式,具有丰富的仿真分析能力.高版本可 以进行单片机等MCU的仿真.Multisim有实际元器 ...

  5. python+selenium自动化软件测试(第12章):Python读写XML文档

    XML 即可扩展标记语言,它可以用来标记数据.定义数据类型,是一种允许用户对自己的标记语言进 行定义的源语言.xml 有如下特征: 首先,它是有标签对组成:<aa></aa> ...

  6. 简说JS中的循环部分

    JS中的循环语句是JS基础的最最重要的部分,没有之一,后面所学的其他的一些重要的知识也是需要在此的基础啥古玩城更高级的设置,先来简单的说一下循环的一些知识点. 一.循环结构的执行步骤 1.声明循环变量 ...

  7. DispatcherTimer和Timer(计时器)

    System.Windows.Threading.DispatcherTimer dTime;        System.Timers.Timer timer;        public Main ...

  8. 为什么a标签中使用img后,高度多了几个像素?

    <li><a href="#"><img src="images/audio.jpg" alt="">& ...

  9. Web桌面应用框架2:著名的WEB桌面应用分析

    前一篇文章里,分析了包括NW.js和electron这种纯JS框架在内的几种Web桌面应用开发方式,实际上还有一种最古老的方式,那就是嵌入WebView的方式. 嵌入WebView的方式和整个程序都是 ...

  10. 关于querySelector 和 document.getElementsByTagName 选中集合问题

    本文解决的问题是 :运用for..of..循环时,edge浏览器报Object doesn't support property or method 'symbol.iterator'问题 以及 符号 ...