GCD(1/2) 队列和分组

苹果提供的基于 C 的一组 API,用于多线程编程

一、队列

并行队列:任务以FIFO顺序出列,但可以同时运行并且可以按任何顺序完成。
串行队列:任务以FIFO顺序一次执行一个。
1、创建自定义队列

dispatch_queue_t queue = dispatch_queue_create(“队列标识符”, NULL);

第一个参数是标识符,可以为空
第二个参数用来表示创建的队列是串行的还是并行的
传入 DISPATCH_QUEUE_SERIAL 或 NULL 表示创建串行队列。
传入 DISPATCH_QUEUE_CONCURRENT 表示创建并行队列。
2、获取主队列(串行队列)

dispatch_queue_t queue = dispatch_get_main_queue();

3、获取全局队列(并行队列)

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

第一个参数标识任务优先级,高、中、低依次为
DISPATCH_QUEUE_PRIORITY_HIGH、
DISPATCH_QUEUE_PRIORITY_DEFAULT、
DISPATCH_QUEUE_PRIORITY_LOW。
一般默认为 DISPATCH_QUEUE_PRIORITY_DEFAULT。
第二参数作为保留字段备用,一般为 0。
注意:由于主队列和全局队列是系统控制的,所以我们无法对其进行 dispatch_resume(queue) 继续 和 dispatch_suspend(queue) 中断

二、线程

同步线程:不具备开辟新线程能力;必须任务执行完成之后才会返回,等待;
dispatch_sync(queue, ^{

});
异步线程:具备开辟新线程的能力;任务加入队列之后立即返回,不等待;
dispatch_async(queue, ^{

});

三、死锁

1、主线程中同步的添加新任务至主队列

dispatch_sync(dispatch_get_main_queue(), ^{
        NSLog(@"new task");
});

2、串行队列 queue 中的任务 A 同步地添加任务 B 至队列 queue

dispatch_queue_t queue = dispatch_queue_create("串行队列", DISPATCH_QUEUE_SERIAL);
dispatch_async(queue, ^{
        NSLog(@"A task");
        dispatch_sync(queue, ^{
            NSLog(@"B task");
        });
});

四、任务组

通过添加任务到任务组可以获取到任务组完成事件
添加任务方式一:

dispatch_group_async(group, queue, ^{
        
});
dispatch_group_sync(group, queue, ^{
        
});

添加任务方式二:
task 开始时调用 dispatch_group_enter(group)
task 结束时调用 dispatch_group_leave(group)
如果 dispatch_group_enter 比 dispatch_group_leave 多,则wait函数等待的线程不会被唤醒和注册 notify 的回调 block 不会执行;
如果 dispatch_group_leave比dispatch_group_enter多,则会引起"Unbalanced call to dispatch_group_leave()"的崩溃。

dispatch_group_wait(group, DISPATCH_TIME_FOREVER);

当前线程会等待任务组中的任务全部完成后,才会继续执行任务(阻塞当前线程)

dispatch_group_notify(group, queue, ^{
       
});

任务组中的任务全部完成后,添加任务至指定队列并执行

五、常用 GCD 函数

1、延迟执行函数
DISPATCH_TIME_NOW
DISPATCH_TIME_FOREVER
dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC))

NSEC_PER_SEC 纳秒/秒 1, 000, 000, 000
NSEC_PER_MSEC 纳秒/毫秒 1, 000, 000
NSEC_PER_USEC 纳秒/微秒 1, 000
可以理解为系统以纳秒为单位。

dispatch_after(time, queue, ^{
        
})

2、单次任务

static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{

});

3、异步执行特定次数任务;执行之后才会返回;

dispatch_apply(count, queue, ^(size_t index) {

})
上一篇:Redux的中间件Middleware不难,我信了^_^


下一篇:ios——GCD基本使用