OC-多线程GCD的使用细节

1>GCD,全称Grand Central Dispatch,”牛逼的中枢调度器”,纯C语言,提供了非常多强大的函数
2>GCD优势:
(1)GCD是苹果公司为多核的并行运算提出的解决方案
(2)GCD会自动利用更多地CPU内核(双核,四核等)
(3)GCD会自动管理线程的生命周期(创建线程,调度任务,销毁线程)
(4)程序员只需告诉GCD想要执行什么任务,不需要编写任何线程管理代码
3>任务和队列
GCD中2个核心概念:
任务:执行什么操作
队列:用来存放任务
GCD使用2个步骤:
(1)定制任务:确定想做得事情
(2)将任务添加到队列中:
    GCD会自动将队列中的任务取出,放到对应的线程中执行
    任务的取出遵循队列的FIFO原则:先进先出,后进后出
4>GCD中有2个用来执行任务的函数
(1)同步方式执行任务
dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);
queue:队列
block:任务
(2)异步方式执行任务
dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
(1),(2)区别:同步在当前线程中执行;异步在另一条线程中执行
5>GCD的队列分为2大类型
(1)并发队列
    可以让多个任务并发(同时)执行(自动开启多个线程同时执行任务)
    并发功能只有在异步(dispatch_async)函数下才有效
创建方法:
dispatch_queue_t queue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
(2)串行队列
    让任务一个戒指一个的执行(一个任务执行完毕后,再执行下一个任务)
创建串行有两种途径:
    使用dispatch_queue_create函数创建
    dispatch_queue_t   queue=dispatch_queue_create(“cn.xxoo.queue”,NULL);
    dispatch_release(queue);//非ARC需要手动释放创建的队列
    使用主队列dispatch_get_main_queue:
    *放入主队列中的任务,队徽放到主线程中执行
    dispatch_queue_t queue=dispatch_get_main_queue();

6>各种队列的执行效果
OC-多线程GCD的使用细节

7>线程间通信示例:
dispatch_async(
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),^{
    //执行耗时的异步操作
    dispatch_async(dispatch_get_main_queue(),^{
        //回到主线程,执行UI刷新操作
    });
});

8>延时执行
(1)调用NSObject的方法
    [self performSelector:@selector(run) withObject:nil afterDelay:2.0];
//2秒后再调用self的run方法
(2)使用GCD函数
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW,(int64_t)(2.0*NSEC_PER_SEC)),dispatch_get_main_queue(),^{
    //2秒后异步执行这里的代码...
});

9>一次性代码
使用dispatch_once函数能保证某段代码在程序运行过程中只被执行一次
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
    //只执行1次的代码(这里默认是线程安全的)
});

10>队列组

有这样一种需求:
首先:分别异步执行2个耗时操作
其次:等2个异步操作都执行完毕后,再回到主线程执行操作
这时可以考虑使用队列组(高效快速地实现)

dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),^{

//执行第一个耗时的异步操作
});

dispatch_group_async(group,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),^{

//执行第二个耗时的异步操作
});

dispatch_group_notify(group,dispatch_get_main_queue(),^{
    //等前面的异步操作都执行完毕后,回到主线程...
});

上一篇:C++版 - 剑指offer面试题28: 字符串的排列


下一篇:cuda网格的限制