【问题标题】:GCD: What happens when two threads want to execute blocks on the main thread at the same timeGCD:当两个线程想同时在主线程上执行块时会发生什么
【发布时间】:2014-08-31 05:53:14
【问题描述】:

我在我的 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 的文档还是自己做一些实验?我可以做什么样的实验?

【问题讨论】:

  • 文档页面的标题回答了这个问题:“schedule blocks for execution”。
  • 总质子反转。

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


【解决方案1】:

您想要的文档是Concurrency Programming Guide。特别是您想要关于 Dispatch Queues 的部分,更重要的是您想要关于 Migrating Away from Threads 的部分。

您不应该认为自己拥有三个线程(事实上,您可能没有)。你可能有三个块。您可能有三个队列。如何以及是否将这些分派到线程是内部实现细节。

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

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

但关键是要记住,这些只是 FIFO 队列,您可以将块放入其中。

【讨论】:

  • 谢谢!很好的答案!
【解决方案2】:

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

对于一个可以运行的简单示例,您可以在此处参考我对这个问题的回答:https://stackoverflow.com/a/20683252/1387258

发生了什么事:

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

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

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

我怎样才能找到这样的答案
我将建议您尝试各种事情,就像我上面建议的那样。主线程仅用于 UI 更新等。尝试在那里进行实验,祝你好运。

【讨论】:

  • 串行线程?并发线程?这没有意义......它应该是主 queue 是一个串行 queue
  • 关于记录在哪里的问题,并发编程指南中对此进行了广泛的介绍:developer.apple.com/library/ios/documentation/General/…
  • 对于OP的具体问题,可能在该页面的表3-1中得到了最简洁的回答,它解释了主要的调度队列和串行队列。
猜你喜欢
  • 1970-01-01
  • 2019-02-11
  • 2017-11-18
  • 2013-10-13
  • 2019-11-15
  • 1970-01-01
  • 1970-01-01
  • 2019-02-27
  • 2014-03-18
相关资源
最近更新 更多