25

好的,我喜欢 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 是串行的,那怎么可能?串行队列如何并行执行操作,或者,如果您愿意,可以乱序执行?

谢谢

4

3 回答 3

59

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);

block1will be executed before block2which will be executed before block3。这是串行队列保证的顺序。

但是,调用dispatch_async()可能会任何块开始执行之前返回。在所有三个块都执行之前不会dispatch_sync()返回!

于 2011-02-17T07:15:33.510 回答
4

既不改变dispatch_async也不dispatch_sync改变块排队的方式。如果队列是串行的,块将以串行的方式执行,如果队列是并发的,则以并发的方式执行。

两者之间的重要区别在于,dispatch_sync将块排队并等待当前执行线程,直到该块被执行,然后dispatch_async才将块排队并继续执行后续指令。

于 2016-04-28T14:45:52.733 回答
1

串行队列一次只能运行一个任务,与同步或异步无关。串行队列只分配一个线程。使用以下示例将更容易理解 -

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

于 2018-12-18T09:36:51.047 回答