在Grand Central Dispatch中使用串行队列的dispatch_async与dispatch_sync

时间:2011-02-17 07:09:45

标签: iphone objective-c ios grand-central-dispatch

好的,我喜欢Grand Central Dispatch并且在使用它之后相对成功,但这是我不完全理解的。

假设我使用

创建了自己的串行队列
dispatch_queue_t myQueue;
myQueue = dispatch_queue_create("myQueue", NULL);

之后我这样做:

dispatch_async(myQueue, ^{
  [self doStuff1];
});

// and a few lines later...

dispatch_sync(myQueue, ^{
  [self doStuff2];
});

第一个调度是异步的。那么,它将同时完成,对吧?如果myQueue是串行的怎么办?串行队列如何并行执行,或者如果不按顺序执行操作?

感谢

3 个答案:

答案 0 :(得分:57)

dispatch_async()表示该块已入队,dispatch_async()返回以在执行块之前将另一个任务/块(可能)排入队列。

使用dispatch_sync(),该块被排队,并且函数将不会继续将另一个任务/块排队,直到执行该块为止。

这些块仍然是连续执行的。你可以执行100个dispatch_async()个调用,每个调用都有一个睡眠时间为100秒的块,而且速度非常快。通过在同一个串行队列上调用dispatch_sync()来跟随它,dispatch_sync()将在10,000秒后返回。


更简单地说:

dispatch_async(serialQ, block1);
dispatch_async(serialQ, block2);
dispatch_sync(serialQ, block3);

block1将在block2之前执行,该block3将在dispatch_async()之前执行。这是串行队列保证的顺序。

但是,对dispatch_sync()的调用可能会在任何块开始执行之前返回。在执行所有三个块之前,{{1}}将返回!

答案 1 :(得分:4)

dispatch_asyncdispatch_sync都不会更改阻止排队的方式。如果队列是串行的,那么如果队列是并发的,则这些块将以并发方式以串行方式执行。

两者之间的重要区别是dispatch_sync对块进行排队并等待当前执行线程,直到执行该块为止,dispatch_async只对该块进行排队并继续执行后续指令。

答案 2 :(得分:1)

Serial Queue一次只能运行一个任务,而无论同步还是异步。串行队列仅分配一个线程。使用以下示例将更易于理解-

假设有两个队列A和B分别运行任务T1和T2,并且T1正在异步执行。如果控制从A传递到B,并且B同步运行T2,则直到T2(dispatch_sync块中的代码块)完成执行的时间将被阻塞。 T2完成后,T1将恢复执行。