GCD线程依赖,GCD队列组,线程监听,线程等待

本文深入探讨GCD中的线程控制技术,包括dispatch_group_notify、dispatch_group_wait及dispatch_group_enter与dispatch_group_leave的使用方法。通过具体示例,解析如何在任务全部完成后再执行后续操作,以及如何通过不同方式实现线程的监听与等待。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.线程监听

有时候经常有这样的需求,AB任务都执行完成之后,刷新界面或者执行其他操作,

/**
 * 队列组 dispatch_group_notify
 */
- (void)groupNotify {
    NSLog(@"begin");
    
    dispatch_group_t group =  dispatch_group_create();
    
    dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        // 追加任务1
        for (int i = 0; i < 2; ++i) {
            NSLog(@"任务1---%@",[NSThread currentThread]);      // 打印当前线程
        }
    });
    
    dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        // 追加任务2
        for (int i = 0; i < 2; ++i) {
            NSLog(@"任务2---%@",[NSThread currentThread]);      // 打印当前线程
        }
    });
    
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        // 等前面的异步任务1、任务2都执行完毕后,回到主线程执行任务
        for (int i = 0; i < 2; ++i) {
            NSLog(@"等待1,2完成后的任务3---%@",[NSThread currentThread]);      // 打印当前线程
        }
        NSLog(@"end");
    });
}

  

 

2.线程等待

暂停当前线程(阻塞当前线程),等待指定的 group 中的任务执行完成后,才会往下继续执行

从dispatch_group_wait相关代码运行输出结果可以看出:

当所有任务执行完成之后,才执行 dispatch_group_wait 之后的操作。但是,使用dispatch_group_wait 会阻塞当前线程。

/**
 * 队列组 dispatch_group_wait
 */
- (void)groupWait {

    NSLog(@"begin");
    
    dispatch_group_t group =  dispatch_group_create();
    
    dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        // 追加任务1
        for (int i = 0; i < 2; ++i) {
            NSLog(@"任务1---%@",[NSThread currentThread]);      // 打印当前线程
        }
    });
    
    dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        // 追加任务2
        for (int i = 0; i < 2; ++i) {
            NSLog(@"任务2---%@",[NSThread currentThread]);      // 打印当前线程
        }
    });
    
    // 等待上面的任务全部完成后,会往下继续执行(会阻塞当前线程)
    dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
    
    dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        // 追加任务3
        for (int i = 0; i < 2; ++i) {
            NSLog(@"任务3---%@",[NSThread currentThread]);      // 打印当前线程
        }
    });
  
}

  

 

3.延伸阅读

  dispatch_group_async队列组添加任务的方式,是把一个任务添加到队列中,执行完成之后从队列中删除

  dispatch_group_async 也可以用dispatch_async + dispatch_group_enter + dispatch_group_leave的方式

  dispatch_group_enter:标志着一个任务追加到 group,也就是group 中未执行完毕任务数+1
  dispatch_group_leave:正好与前者相反,
标志着一个任务从group中删除,也就是group 中未执行完毕任务数-1

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


给个例子,打印一下,会更好理解。
/**
 * 队列组 Enter  Leave
 */
- (void)groupEnterLeave {
    NSLog(@"begin");
    
    dispatch_group_t group =  dispatch_group_create();
    
    dispatch_group_enter(group);
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        // 追加任务1
        for (int i = 0; i < 2; ++i) {
            NSLog(@"任务1---%@",[NSThread currentThread]);      // 打印当前线程
        }
        dispatch_group_leave(group);
    });
    
    dispatch_group_enter(group);
    dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        // 追加任务2
        for (int i = 0; i < 2; ++i) {
            NSLog(@"任务2---%@",[NSThread currentThread]);      // 打印当前线程
        }
        dispatch_group_leave(group);
    });
    
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        // 等前面的异步任务1、任务2都执行完毕后,回到主线程执行任务
        for (int i = 0; i < 2; ++i) {
            NSLog(@"等待1,2完成后的任务3---%@",[NSThread currentThread]);      // 打印当前线程
        }

        NSLog(@"end");
    });
}

 

 

  但是如果把上面任务1或者任务2的这句代码注释了dispatch_group_leave(group);

  那么程序就只会执行任务1 2 ,永远不会执行任务3 ,因为只有当 group 中未执行完毕任务数为0的时候,才会使dispatch_group_wait解除阻塞,以及执行追加到dispatch_group_notify中的任务

  注释了之后无论是使用dispatch_group_notify还是dispatch_group_wait,打印的情况都如下

 

 
 

 

转载于:https://www.cnblogs.com/huangzhenwei/p/9728582.html

内容概要:本文介绍了奕斯伟科技集团基于RISC-V架构开发的EAM2011芯片及其应用研究。EAM2011是一款高性能实时控制芯片,支持160MHz主频和AI算法,符合汽车电子AEC-Q100 Grade 2和ASIL-B安全标准。文章详细描述了芯片的关键特性、配套软件开发套件(SDK)和集成开发环境(IDE),以及基于该芯片的ESWINEBP3901开发板的硬件资源和接口配置。文中提供了详细的代码示例,涵盖时钟配置、GPIO控制、ADC采样、CAN通信、PWM输出及RTOS任务创建等功能实现。此外,还介绍了硬件申领流程、技术资料获取渠道及开发建议,帮助开发者高效启动基于EAM2011芯片的开发工作。 适合人群:具备嵌入式系统开发经验的研发人员,特别是对RISC-V架构感兴趣的工程师和技术爱好者。 使用场景及目标:①了解EAM2011芯片的特性和应用场景,如智能汽车、智能家居和工业控制;②掌握基于EAM2011芯片的开发板和芯片的硬件资源和接口配置;③学习如何实现基本的外设驱动,如GPIO、ADC、CAN、PWM等;④通过RTOS任务创建示例,理解多任务处理和实时系统的实现。 其他说明:开发者可以根据实际需求扩展这些基础功能。建议优先掌握《EAM2011参考手册》中的关键外设寄存器配置方法,这对底层驱动开发至关重要。同时,注意硬件申领的时效性和替代方案,确保开发工作的顺利进行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值