iOS-多线程dispatch_semaphore_t dispatch_queue_t dispatch_group_t常见用法场景

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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");
    });

以上是关于iOS-多线程dispatch_semaphore_t dispatch_queue_t dispatch_group_t常见用法场景的主要内容,如果未能解决你的问题,请参考以下文章

IOS多线程安全(线程锁)

使用GCD中的dispatch_semaphore(信号量)处理一个界面多个请求(把握AFNet网络请求完成的正确时机)

使用 dispatch_semaphore 时 iOS 14 崩溃僵尸

多线程 加锁

dispatch_semaphore

iOS各种锁的比较