同步分派的工作项是否始终在 iOS 的主线程上独立执行(无论它们是分派到并发、串行、全局还是自定义队列)?
我检查了不同的情况,发现同步分派的工作项始终在 iOS 的主线程上执行,但是,在某些情况下,同步分派的工作项可能在非主线程的线程上执行,因为它可能是我的实验没有涵盖所有情况。
我尝试过以下案例:
同步调度到自定义并发队列
同步调度到自定义串行队列
同步调度到全局队列
你问:
同步分派的工作项是否始终在 iOS 的主线程上独立执行(无论它们是分派到并发、串行、全局还是自定义队列)?
首先,作为澄清一点,我假设您指的是从主线程同步调度的那些项目。如果您从某个随机后台线程同步调度到某个随机队列(主队列除外),那么它will 可能会在 current 线程上运行它,而不是与其他队列关联的线程,当然也不是主线程。
其次,作为性能优化,同步调度时,它会“尽可能”尝试使用当前线程。无论如何,这样做是为了避免调用线程被sync
阻塞时不必要的上下文切换。正如文档所说(添加了强调):
作为性能优化,此函数在当前线程上执行块现在,我知道您已经尝试了各种演绎来表明它不在当前线程上运行的情况。我也没有成功地尝试让它在另一个线程上运行。为了添加到您的场景列表中,我还尝试了以下情况:后台队列繁忙、后台队列具有更高的 QoS、有或没有只要有可能, …
enforceQoS
选项、后台队列有一些特定的目标队列等.但是我们未能表现出这种优化不发生的场景并不意味着它永远不会发生。毫无疑问,在某些边缘情况下它无法安全地执行此优化。 (我已经看到了一些隐晦的提及,即它可能会在高争用场景中选择退出这种性能情况,但我尚未能够体现它,因此我无法进一步评论。)
底线,享受这种优化的性能优势,因为它似乎总是使用它,但从不依赖它。假设这种优化总是会发生是不明智的,因为苹果已经明确警告我们这种优化可能不会发生。
文档继续说道:
…有一个例外:提交到主调度队列的块始终在主线程上运行。我知道此警告不适用于您的情况,但为了完整起见,我添加此免责声明。
除了简单的同步模式之外,典型的“从主线程调度到另一个队列”用于从主线程中获取工作。在这些场景中,我们总是异步调度(因为重点是避免阻塞当前线程)。