GCD系列是阅读官方文件和在实践中总结的一些常见的GCD用法,基本涉及全部的GCD内容形成的集合文章,文章重点在与精简和全面覆盖。
学习本集合你可以了解:
1. GCD是如何做到多线程调度的
2. 对比其他iOS的多线程方案,GCD的优势和劣势
3. 如何使用GCD相关的API我将在后续不断补充详细内容和实际案例, 欢迎关注,提问和讨论
03-dispatch_after/dispatch_time-延迟调度和操作
04-dispatch_barrier_sync/async-线程阻塞
dispatch_barrier_sync
# Submits a barrier block for synchronous execution on a dispatch queue.
# relevant only on DISPATCH_QUEUE_CONCURRENT queues
void dispatch_barrier_sync(dispatch_queue_t queue, DISPATCH_NOESCAPE dispatch_block_t block);
void dispatch_barrier_sync_f(dispatch_queue_t queue, void *_Nullable context, dispatch_function_t work);
dispatch_barrier_async
void dispatch_barrier_async(dispatch_queue_t queue, dispatch_block_t block);
demo
dispatch_queue_t concurrentQueue = dispatch_queue_create("concurrent", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(concurrentQueue, ^(){
NSLog(@"dispatch-1");
});
dispatch_async(concurrentQueue, ^(){
NSLog(@"dispatch-2");
});
dispatch_barrier_async(concurrentQueue, ^(){
sleep(2);
NSLog(@"dispatch-barrier");
sleep(3);
});
dispatch_async(concurrentQueue, ^(){
NSLog(@"dispatch-3");
});
dispatch_async(concurrentQueue, ^(){
NSLog(@"dispatch-4");
});
2016-11-05 17:15:27.117 Multithreading[16339:491841] dispatch-2
2016-11-05 17:15:27.117 Multithreading[16339:491842] dispatch-1
前面两个线程异步执行
barrier阻塞之后的线程, 先执行完barrier内的block, 才能继续执行后面的线程
也就是说, dispatch_barrier_async 作用是在并行队列中,等待前面两个操作并行操作完成,这里是并行输出
然后执行dispatch_barrier_async中的操作,(现在就只会执行这一个操作)执行完成后,
最后该并行队列恢复原有执行状态,继续并行执行
2016-11-05 17:15:29.192 Multithreading[16339:491842] dispatch-barrier
2016-11-05 17:15:32.264 Multithreading[16339:491842] dispatch-3
2016-11-05 17:15:32.264 Multithreading[16339:491844] dispatch-4
小结
Barrierblocks只会在创建DISPATCH_QUEUE_CONCURRENT这一特定类型的时候才会有栅栏的作用。
其作用具体表现为:
dispatch_barrier_async提交的Block前后的Block会按顺序提交到Queue,
然后Queue会等待barrier之前的Block执行完毕之后才执行barrier这个Block,
而barrier之后的Block必须等待barrier执行完毕之后才执行。
即全部的Block都按顺序先插入到队列中,执行的顺序会按照:前–barrier–后。
dispatch_barrier_sync先只提交barrier和barrier之前的Block,
然后Queue会等待barrier之前的Block执行完毕之后才执行barrier这个Block,
而barrier之后的Block必须等待barrier执行完毕之后才提交到Queue并执行。
共同点:
1、等待在它前面插入队列的任务先执行完
2、等待他们自己的任务执行完再执行后面的任务
- Barrier blocks only behave specially when submitted to queues created with
- the DISPATCH_QUEUE_CONCURRENT attribute; on such a queue, a barrier block
- will not run until all blocks submitted to the queue earlier have completed,
- and any blocks submitted to the queue after a barrier block will not run
- until the barrier block has completed.
dispatch_barrier_sync/async方法一定要在自定义的DISPATCH_QUEUE_CONCURRENT类型上使用,否则他会表现的和dispatch_sync/dispatch_async一样 - When submitted to a a global queue or to a queue not created with the
- DISPATCH_QUEUE_CONCURRENT attribute, barrier blocks behave identically to
- blocks submitted with the dispatch_async()/dispatch_sync() API.