ios 串行队列上的 dispatch_async 和 dispatch_sync 之间的区别?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19822700/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Difference between dispatch_async and dispatch_sync on serial queue?
提问by JRG-Developer
I've created a serial queue like this:
我创建了一个这样的串行队列:
dispatch_queue_t _serialQueue = dispatch_queue_create("com.example.name", DISPATCH_QUEUE_SERIAL);
What's the difference between dispatch_async
called like this
什么之间的差异dispatch_async
被称为像这样
dispatch_async(_serialQueue, ^{ /* TASK 1 */ });
dispatch_async(_serialQueue, ^{ /* TASK 2 */ });
And dispatch_sync
called like this on this serial queue?
并dispatch_sync
在这个串行队列上这样调用?
dispatch_sync(_serialQueue, ^{ /* TASK 1 */ });
dispatch_sync(_serialQueue, ^{ /* TASK 2 */ });
My understanding is that, regardless of which dispatch method is used, TASK 1
will be executed and completed before TASK 2
, correct?
我的理解是,无论使用哪种dispatch方法,TASK 1
都会在之前执行完成TASK 2
,对吗?
回答by Bryan Chen
Yes. Using serial queue ensure the serial execution of tasks. The only difference is that dispatch_sync
only return after the block is finished whereas dispatch_async
return after it is added to the queue and may not finished.
是的。使用串行队列确保任务的串行执行。唯一的区别是dispatch_sync
只在块完成后dispatch_async
返回,而在将其添加到队列后返回并且可能未完成。
for this code
对于此代码
dispatch_async(_serialQueue, ^{ printf("1"); });
printf("2");
dispatch_async(_serialQueue, ^{ printf("3"); });
printf("4");
It may print 2413
or 2143
or 1234
but 1
always before 3
它可能会打印2413
或2143
或1234
但1
总是在此之前3
for this code
对于此代码
dispatch_sync(_serialQueue, ^{ printf("1"); });
printf("2");
dispatch_sync(_serialQueue, ^{ printf("3"); });
printf("4");
it always print 1234
它总是打印 1234
Note: For first code, it won'tprint 1324
. Because printf("3")
is dispatched afterprintf("2")
is executed. And a task can only be executed afterit is dispatched.
注意:对于第一个代码,它不会打印1324
. 因为printf("3")
是在printf("2")
执行后分派的。并且任务只有在分派后才能执行。
The execution time of the tasks doesn't change anything. This code always print 12
任务的执行时间不会改变任何东西。此代码始终打印12
dispatch_async(_serialQueue, ^{ sleep(1000);printf("1"); });
dispatch_async(_serialQueue, ^{ printf("2"); });
What may happened is
可能发生的事情是
- Thread 1: dispatch_async a time consuming task (task 1) to serial queue
- Thread 2: start executing task 1
- Thread 1: dispatch_async another task (task 2) to serial queue
- Thread 2: task 1 finished. start executing task 2
- Thread 2: task 2 finished.
- 线程 1:dispatch_async 一个耗时的任务(任务 1)到串行队列
- 线程2:开始执行任务1
- 线程 1:dispatch_async 另一个任务(任务 2)到串行队列
- 线程 2:任务 1 完成。开始执行任务2
- 线程 2:任务 2 完成。
and you always see 12
你总是看到 12
回答by Dave DeLong
The difference between dispatch_sync
and dispatch_async
is simple.
dispatch_sync
和之间的区别dispatch_async
很简单。
In both of your examples, TASK 1
will always execute before TASK 2
because it was dispatched before it.
在您的两个示例中,TASK 1
将始终在之前执行,TASK 2
因为它是在它之前调度的。
In the dispatch_sync
example, however, you won't dispatch TASK 2
until after TASK 1
has been dispatched and executed. This is called "blocking". Your code waits (or "blocks") until the task executes.
dispatch_sync
但是,在该示例中,您将TASK 2
在TASK 1
已分派并执行之后才进行分派。这称为“阻塞”。您的代码等待(或“阻塞”)直到任务执行。
In the dispatch_async
example, your code will not wait for execution to complete. Both blocks will dispatch (and be enqueued) to the queue and the rest of your code will continue executing on that thread. Then at some point in the future, (depending on what else has been dispatched to your queue), Task 1
will execute and then Task 2
will execute.
在dispatch_async
示例中,您的代码不会等待执行完成。两个块都将分派(并入队)到队列中,其余代码将继续在该线程上执行。然后在未来的某个时刻(取决于其他已分派到您的队列的内容),Task 1
将执行,然后Task 2
将执行。
回答by rd_
It is all related to main queue. There are 4 permutations.
这一切都与主队列有关。有4种排列。
i) Serial queue, dispatch async : Here the tasks will execute one after the other, but the main thread(effect on UI) will not wait for return
i) 串行队列,异步调度:这里的任务将一个接一个地执行,但主线程(对 UI 的影响)不会等待返回
ii) Serial queue, dispatch sync: Here the tasks will execute one after the other, but the main thread(effect on UI) will show lag
ii) 串行队列,调度同步:这里的任务会一个接一个执行,但主线程(对UI的影响)会出现滞后
iii) Concurrent queue, dispatch async : Here the tasks will execute in parallel and the main thread(effect on UI ) will not wait for return and will be smooth.
iii) 并发队列,异步调度:这里的任务将并行执行,主线程(对 UI 的影响)不会等待返回并且会很流畅。
iv) Concurrent queue, dispatch sync : Here the tasks will execute in parallel, but the main thread(effect on UI) will show lag
iv) 并发队列,调度同步:这里的任务将并行执行,但主线程(对 UI 的影响)会出现滞后
Your choice of concurrent or serial queue depends on if you need an output from a previous task for the next one. If you depend on the previous task, adopt the serial queue else take concurrent queue.
您选择并发队列还是串行队列取决于您是否需要为下一个任务提供前一个任务的输出。如果依赖上一个任务,则采用串行队列,否则采用并发队列。
And lastly this is a way of penetrating back to the main thread when we are done with our business :
最后,这是一种在我们完成业务后返回到主线程的方法:
DispatchQueue.main.async {
// Do something here
}