GCD:当两个线程想要同时在主线程上执行块时会发生什么

时间:2014-07-10 02:41:42

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

我在我的IOS应用程序中使用GCD。我有三个线程:主线程,线程2和线程3.

以下代码在线程2上执行,

    dispatch_async(dispatch_get_main_queue(), ^{ code block 1 ...

所以代码块1将在主线程上执行。如果在代码块1完成运行之前在线程3中执行以下代码会发生什么:

    dispatch_async(dispatch_get_main_queue(), ^{ code block 2 ...

将bock2等到bock1终止?

我如何找到这些问题的答案?我应该阅读APPLE的文件或自己做一些实验吗?我可以做什么样的实验?

2 个答案:

答案 0 :(得分:2)

您想要的文件是Concurrency Programming Guide。特别是你需要关于Dispatch Queues的部分,更重要的是你想要关于从线程迁移的部分。

你不应该认为自己有三个线程(事实上,你可能没有)。你可能有三个街区。你可能有三个队列。如何将这些调度到线程是一个内部实现细节。

在GCD中,单词" dispatch"意味着"放在队列中。"当块到达系统队列的前面时,它将有资格在可用线程上运行。队列可能会进入其他队列,但最终它们必须绑定到其中一个系统队列(否则它们永远不会执行)。

主队列是一个串行队列。与其他串行队列一样,每个块必须在允许下一个块运行之前完成(这就是为什么如果你不小心你可能会使主队列饿死或死锁)。还有并发队列,只需要在考虑下一个块之前启动每个块。

但关键是要记住,这些只是FIFO队列,你可以把块放到。

答案 1 :(得分:1)

答案在于主线程是一个串行队列。也就是说,在您的示例中,块2将等待块1完成,然后才能执行。但是要小心,如果你的第一个块被某些东西锁定或者等待了很长时间,那么块2的执行可能会被延迟很长时间甚至无限期。

有关您可以运行的简单示例,请参阅此问题的答案:https://stackoverflow.com/a/20683252/1387258

发生了什么:

  • 请求collectionView从另一个线程重新加载主线程上的数据。
  • 然后请求collectionView(例如)添加新部分,一堆项目等。

现在,如果您的第二个区块依赖于您的第一个区块,这一点至关重要。也就是说,您可能需要首先使布局无效,然后才能向其添加新项目。

第二种情况可能是:您需要更改集合视图上的布局,然后才能更新其内容。

如何找到的答案 我会建议你尝试各种各样的事情,比如我上面提到的。主要线程仅用于UI更新。尝试在那里试验,祝你好运。