iOS中的多线程(关于GCD 的队列组)

1,147 阅读2分钟

「这是我参与11月更文挑战的第8天,活动详情查看:2021最后一次更文挑战

GCD队列组

有时候会有这样的需求:分别异步执行2个耗时任务,然后当2个耗时任务都执行完毕后再回到主线程执行任务。这时候可以用到 GCD 的队列组

  • 使用 dispatch_group_create 创建一个队列组
  • 使用 dispatch_group_async 将任务添加到队列中

dispatch_group_notify

  • 监听 group 中任务的完成状态,当 group 中所有的任务都执行完成后,就会收到 dispatch_group_notify 通知
  • 使用 dispatch_group_notify,不会阻塞当前线程

示例:

//创建一个队列组
dispatch_group_t group = dispatch_group_create();

//创建一个队列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

NSLog(@"当前线程--0--%@",[NSThread currentThread]);

//将任务放到队列中
dispatch_group_async(group, queue, ^{
    for (NSInteger i = 0; i<3; i++) {
        NSLog(@"任务1----%@",[NSThread currentThread]);
    }
});

//将任务放到队列中
dispatch_group_async(group, queue, ^{
    for (NSInteger i = 0; i<3; i++) {
        NSLog(@"任务2----%@",[NSThread currentThread]);
    }
});

//当这个队列组的所有队列全部完成,就会收到这个消息
dispatch_group_notify(group, queue, ^{
    NSLog(@"1和2执行完毕 -- %@",[NSThread currentThread]);
});

NSLog(@"当前线程--3--%@",[NSThread currentThread]);

log:

Snip20211107_73.png

dispatch_group_wait

  • 监听 group 中任务的完成状态,当 group 中所有的任务都执行完成后,就会收到 dispatch_group_notify 通知
  • 使用 dispatch_group_notify,会阻塞当前线程

示例:

//创建一个队列组
dispatch_group_t group = dispatch_group_create();

//创建一个队列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

NSLog(@"当前线程--0--%@",[NSThread currentThread]);

//将任务放到队列中
dispatch_group_async(group, queue, ^{
    for (NSInteger i = 0; i<3; i++) {
        NSLog(@"任务1----%@",[NSThread currentThread]);
    }
});

//将任务放到队列中
dispatch_group_async(group, queue, ^{
    for (NSInteger i = 0; i<3; i++) {
        NSLog(@"任务2----%@",[NSThread currentThread]);
    }
});

//设置dispatch_group_wait
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);

//阻塞当前线程,当这个队列组的所有队列全部完成,才会继续执行
NSLog(@"当前线程--3--%@",[NSThread currentThread]);

log:

Snip20211107_74.png

dispatch_group_enter 和 dispatch_group_leave

  • dispatch_group_enter 标志一个任务追加到 group,执行一次,相当于 group 中未执行完毕任务数 +1

  • dispatch_group_leave 标志着一个任务离开了 group,执行一次,相当于 group 中未执行完毕任务数 -1

  • dispatch_group_enterdispatch_group_leave 组合,其实等同于 dispatch_group_async

  • group 中未执行完毕任务数为 0 的时,才会使 dispatch_group_wait 解除阻塞,以及执行追加到 dispatch_group_notify 中的任务

示例:

//创建一个队列组
dispatch_group_t group = dispatch_group_create();

//创建一个队列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

NSLog(@"当前线程--0--%@",[NSThread currentThread]);

//将任务放到队列组
dispatch_group_enter(group);
dispatch_async(queue, ^{
    for (NSInteger i = 0; i<3; i++) {
        NSLog(@"任务1----%@",[NSThread currentThread]);
    }
    
    //将任务拿出队列组
    dispatch_group_leave(group);
});

//将任务放到队列组
dispatch_group_enter(group);
dispatch_async(queue, ^{
    for (NSInteger i = 0; i<3; i++) {
        NSLog(@"任务2----%@",[NSThread currentThread]);
    }
    
    //将任务拿出队列组
    dispatch_group_leave(group);
});

//设置dispatch_group_wait
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);

//阻塞当前线程,当这个队列组的所有队列全部完成,才会继续执行
NSLog(@"当前线程--3--%@",[NSThread currentThread]);

log: Snip20211107_75.png