iOS 中不同线程上同步提交的工作项的执行

问题描述 投票:0回答:1

同步分派的工作项是否始终在 iOS 的主线程上独立执行(无论它们是分派到并发、串行、全局还是自定义队列)?

我检查了不同的情况,发现同步分派的工作项始终在 iOS 的主线程上执行,但是,在某些情况下,同步分派的工作项可能在非主线程的线程上执行,因为它可能是我的实验没有涵盖所有情况。

我尝试过以下案例:

  • 同步调度到自定义并发队列

  • 同步调度到自定义串行队列

  • 同步调度到全局队列

ios swift asynchronous concurrency grand-central-dispatch
1个回答
0
投票

你问:

同步分派的工作项是否始终在 iOS 的主线程上独立执行(无论它们是分派到并发、串行、全局还是自定义队列)?

首先,作为澄清一点,我假设您指的是从主线程同步调度的那些项目。如果您从某个随机后台线程同步调度到某个随机队列(主队列除外),那么它will 可能会在 current 线程上运行它,而不是与其他队列关联的线程,当然也不是主线程。

其次,作为性能优化,同步调度时,它会“尽可能”尝试使用当前线程。无论如何,这样做是为了避免调用线程被

sync

 阻塞时不必要的上下文切换。正如
文档所说(添加了强调):

作为性能优化,此函数在当前线程上执行块

只要有可能,

现在,我知道您已经尝试了各种演绎来表明它不在当前线程上运行的情况。我也没有成功地尝试让它在另一个线程上运行。为了添加到您的场景列表中,我还尝试了以下情况:后台队列繁忙、后台队列具有更高的 QoS、有或没有

enforceQoS

 选项、后台队列有一些特定的目标队列等.

但是我们未能表现出这种优化不发生的场景并不意味着它永远不会发生。毫无疑问,在某些边缘情况下它无法安全地执行此优化。 (我已经看到了一些隐晦的提及,即它可能会在高争用场景中选择退出这种性能情况,但我尚未能够体现它,因此我无法进一步评论。)

底线,享受这种优化的性能优势,因为它似乎总是使用它,但从不依赖它。假设这种优化总是会发生是不明智的,因为苹果已经明确警告我们这种优化可能不会发生。


顺便说一句,这种性能优化有一个众所周知的例外。也就是说,如果您位于后台线程并同步分派到主线程,它将始终在主线程上运行分派的代码,而不是当前线程。正如

文档继续说道:

…有一个例外:提交到主调度队列的块始终在主线程上运行。

我知道此警告不适用于您的情况,但为了完整起见,我添加此免责声明。


最后一些注意事项:

  • 我们很少从主线程同步调度。一个常见的例外是进行非常快速的同步以消除数据竞争。但是,永远不应该从主线程同步分派任何缓慢的内容。

    除了简单的同步模式之外,典型的“从主线程调度到另一个队列”用于从主线程中获取工作。在这些场景中,我们总是异步调度(因为重点是避免阻塞当前线程)。

  • 从主线程同步分派的代码是否在主线程上运行这一事实并不重要。无论哪种方式,您都会阻塞主线程,并且运行分派代码的线程并不真正相关。只是不要编写依赖于在主线程上运行的代码:您没有这样的正式保证。

© www.soinside.com 2019 - 2024. All rights reserved.