zoukankan      html  css  js  c++  java
  • iOS-多线程dispatch_semaphore_t dispatch_queue_t dispatch_group_t常见用法场景

    • dispatch_semaphore_t 用法,dispatch_semaphore_create 创建信号量实际就是创建的对象设置最大并发数.不得小于0, 小于0导致崩溃,dispatch_semaphore_wait , 减少一个信号量, 比如创建的对象信号量是5, wait一次就减少一个信号量,信号量变为4, 当信号量为0的时候当前线程就会等待,直到信号量>0的时候才会往下进行.dispatch_semaphore_signal 增加一个信号量,减少与增加信号量是成对出现的.
    dispatch_semaphore_t semap = dispatch_semaphore_create(1); // 控制最大并发数1条新线程 此时下面操作是线程安全的
    dispatch_semaphore_wait(semap, DISPATCH_TIME_FOREVER);// 此时信号量由1 变为 0 ,即使下面有任务也不会再执行, 因为信号量为0
    // 单个线程操作区域... 线程安全
    dispatch_semaphore_signal(semap);
    
    • 第一种常见用法 group + queue 使用场景: 单次, 多个任务同时执行, 自动开启多个线程,最后执行完毕在回调处理执行完毕的结果
    • 缺点: 不能控制最大并发数, 操作同一资源不安全
    
    // DISPATCH_QUEUE_CONCURRENT 生成一个并发队列(可以有多条线程)
        dispatch_queue_t queue = dispatch_queue_create("sendrequest", DISPATCH_QUEUE_CONCURRENT);
        // 创建group
        dispatch_group_t group = dispatch_group_create();
    // 多个耗时任务同时进行 加入group中同时进行,执行完毕监听回调
        dispatch_group_async(group, queue, ^{
            NSLog(@"1");
            sleep(2);
            NSLog(@"1+");
        });
        dispatch_group_async(group, queue, ^{
            NSLog(@"2");
        });
        dispatch_group_async(group, queue, ^{
            NSLog(@"3");
        });
    
        // group任务全部执行完毕回调
        dispatch_group_notify(group, queue, ^{
            NSLog(@"done");
        });
    
    
    • 第二种使用场景 semaphore + queue 场景: 多次(有100个任务需要执行, 例如数据库100条数据,需要上传,每条创建一个任务,开2个线程), 控制最大并发数(后台开2个线程), group中不能控制最大并发数, 操作数据线程加锁,保证线程安全
    • 缺点不能处理回调
    
        dispatch_semaphore_t semap = dispatch_semaphore_create(2); // 控制最大并发数2条新线程
        // DISPATCH_QUEUE_CONCURRENT 生成一个并发队列(可以有多条线程)
        dispatch_queue_t queue = dispatch_queue_create("sendrequest", DISPATCH_QUEUE_CONCURRENT);
        // 10个任务, 最大并发2, 
        for (int i = 0; i < 10; i++) {
            dispatch_async(queue, ^{
                    dispatch_semaphore_wait(semap, DISPATCH_TIME_FOREVER);
                    // 线程操作区域
                     dispatch_semaphore_signal(semap);
                });
        }
    
    
    • 第三种场景组合用法: dispatch_semaphore_t(设置最大并发数) + dispatch_queue_t(创建并发队列) + dispatch_group_t(监听任务完成回调) 可以处理任务完成回调, 可设置最大并发数
    
    dispatch_semaphore_t semap = dispatch_semaphore_create(2); // 控制最大并发数2条新线程
        // DISPATCH_QUEUE_CONCURRENT 生成一个并发队列(可以有多条线程)
        dispatch_queue_t queue = dispatch_queue_create("sendrequest", DISPATCH_QUEUE_CONCURRENT);
        dispatch_group_t group = dispatch_group_create();
        
        for (int i = 0; i < 10; i++) {
            dispatch_group_async(group, queue, ^{
                dispatch_semaphore_wait(semap, DISPATCH_TIME_FOREVER);
                // 线程操作区域 最多有两个线程在此做事情
                dispatch_semaphore_signal(semap);
            });
        }
         // group任务全部执行完毕回调
        dispatch_group_notify(group, queue, ^{
            NSLog(@"done");
        });
    
  • 相关阅读:
    AtCoder Grand Contest 019
    upd 2020.10.31
    ubuntu 自动配置脚本
    linux下gcc、g++不同版本的安装和切换
    fixes for 100% disk usage on Windows 10
    简单聊聊VisualStudio的断点调试
    运算符重载
    设计模式之桥接模式
    使用C#进行数据库增删改查ADO.NET(三)
    使用C#进行数据库增删改查ADO.NET(二)
  • 原文地址:https://www.cnblogs.com/adampei-bobo/p/9078640.html
Copyright © 2011-2022 走看看