• 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");
        });
    
  • 相关阅读:
    Service Name Port Number Transport Protocol tcp udp 端口号16bit
    linux linux 互传文件 win 不通过 ftp sftp 往linux 传文件(文件夹)
    soft deletion Google SRE 保障数据完整性的手段
    Taylor series
    Taylor's theorem
    Moving average
    REQUEST
    Unix file types
    mysqld.sock
    Tunneling protocol
  • 原文地址:https://www.cnblogs.com/adampei-bobo/p/9078640.html
Copyright © 2020-2023  润新知