130

我创建了一个这样的串行队列:

    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,对吗?

4

3 回答 3

420

是的。使用串行队列保证任务的串行执行。唯一的区别是dispatch_sync只有在块完成后才返回,而dispatch_async在将其添加到队列并且可能未完成后返回。

对于此代码

dispatch_async(_serialQueue, ^{ printf("1"); });
printf("2");
dispatch_async(_serialQueue, ^{ printf("3"); });
printf("4");

它可能会打印2413214312341总是在之前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

于 2013-11-06T21:02:32.223 回答
19

dispatch_sync和之间的区别dispatch_async很简单。

在您的两个示例中,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.

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.

于 2013-11-06T21:05:34.227 回答
6

It is all related to main queue. There are 4 permutations.

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

ii) Serial queue, dispatch sync: Here the tasks will execute one after the other, but the main thread(effect on UI) will show lag

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.

iv) Concurrent queue, dispatch sync : Here the tasks will execute in parallel, but the main thread(effect on UI) will show lag

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
}
于 2018-07-30T06:56:58.787 回答