• GCD之信号量机制二


    在前面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关键字有一样的效果。

  • 相关阅读:
    Uploader 文件上传
    filters过滤器的使用
    Calendar中遇到的问题
    中科院之旅
    Python基础教程:列表推导式详解
    不会也要知道的,Python四种实现排序的方法
    2021字节跳动校招秋招算法面试真题解题报告--leetcode19 删除链表的倒数第 n 个结点,内含7种语言答案
    2021字节跳动校招秋招算法面试真题解题报告--leetcode206 反转链表,内含7种语言答案
    求协方差
    国外卡组织的 交换费-interchangefee(发卡行服务费) 和 银联对比
  • 原文地址:https://www.cnblogs.com/yulei126/p/6783209.html
Copyright © 2020-2023  润新知