串行队列上的dispatch_async和dispatch_sync之间的区别?
我已经创build了一个这样的串行队列:
dispatch_queue_t _serialQueue = dispatch_queue_create("com.example.name", DISPATCH_QUEUE_SERIAL);
像这样调用dispatch_async
什么区别
dispatch_async(_serialQueue, ^{ /* TASK 1 */ }); dispatch_async(_serialQueue, ^{ /* TASK 2 */ });
在此串行队列上调用dispatch_sync
?
dispatch_sync(_serialQueue, ^{ /* TASK 1 */ }); dispatch_sync(_serialQueue, ^{ /* TASK 2 */ });
我的理解是,无论使用哪种调度方法, TASK 1
都将在TASK 2
之前执行并完成,对吗?
是。 使用串行队列确保任务的串行执行。 唯一的区别是, dispatch_sync
只在块完成后返回,而dispatch_async
在将其添加到队列后返回并可能没有完成。
为此代码
dispatch_async(_serialQueue, ^{ printf("1"); }); printf("2"); dispatch_async(_serialQueue, ^{ printf("3"); }); printf("4");
它可以打印2413
或2143
或1234
但总是在3
之前
为此代码
dispatch_sync(_serialQueue, ^{ printf("1"); }); printf("2"); dispatch_sync(_serialQueue, ^{ printf("3"); }); printf("4");
它总是打印1234
注意:对于第一个代码,它不会打印1324
。 因为printf("3")
在执行 printf("2")
后被调度。 任务只能在调度之后执行。
任务的执行时间不会改变任何东西。 这个代码总是打印12
dispatch_async(_serialQueue, ^{ sleep(1000);printf("1"); }); dispatch_async(_serialQueue, ^{ printf("2"); });
可能发生的事情是
- 线程1:dispatch_async一个耗时的任务(任务1)到串行队列
- 线程2:开始执行任务1
- 线程1:dispatch_async另一个任务(任务2)到串行队列
- 线程2:任务1完成。 开始执行任务2
- 线程2:任务2完成。
你总是看到12
dispatch_sync
和dispatch_async
之间的区别很简单。
在你的两个例子中, TASK 1
总是在TASK 2
之前执行,因为它在它之前被调度。
然而,在dispatch_sync
示例中,直到TASK 1
被分派并执行之后,您才会调度TASK 2
。 这被称为“阻塞” 。 您的代码将等待(或“阻止”),直到执行任务。
在dispatch_async
示例中,您的代码不会等待执行完成。 两个块都将调度(并入队)到队列中,其余的代码将继续在该线程上执行。 然后在将来的某个时刻,(取决于还有什么被派往你的队列), Task 1
将被执行,然后Task 2
将被执行。