ios - 大中央调度 : What happens when queues get overloaded?

标签 ios swift grand-central-dispatch

我在 GCD 的文档或教程中没有找到一个非常简单的问题:如果我将工作提交到队列的速度快于处理和删除的速度,会发生什么?我知道 GCD 队列没有大小限制,是否会一直堆积到程序内存不足为止?有什么办法可以妥善处理这种情况吗?

最佳答案

What happens if I'm submitting work to queues faster than it's being processed and removed?

这取决于。

  • 如果将任务分派(dispatch)到单个/共享串行队列,它们只会被添加到队列中,并且将以 FIFO 方式处理它们。没问题。内存是你唯一的限制。

  • 但是,如果将任务分派(dispatch)到并发队列,最终会出现“线程爆炸”,并且您将很快耗尽可用于该服务质量 (QoS) 的有限数量的工作线程。如果操作系统需要利用相同 QoS 的队列,这可能会导致不可预测的行为。因此,您必须非常小心,以避免这种线程爆炸。

    参见 WWDC 2015 关于线程爆炸的讨论 Building Responsive and Efficient Apps with GCD并再次在 WWDC 2016 Concurrent Programming With GCD in Swift 3 .

Is there any way to properly handle this situation?

很难抽象地回答这个问题。不同的情况需要不同的解决方案。

对于线程爆炸的情况,解决方案是使用concurrentPerform来约束并发程度(将并发限制为设备上的核心数量)。或者我们使用操作队列及其 maxConcurrentOperationCount 来将并发程度限制在合理的范围内。还有其他模式,但其想法是将并发限制为适合相关设备的并发。

但是,如果您只是将大量任务分派(dispatch)到串行队列,那么您无能为力(除了寻找并行机会,以有效利用所有 CPU 核心)。但这没关系,因为这就是队列的全部目的,让它按照提交的顺序执行任务,即使队列无法跟上。如果它不遵循这种 FIFO 类型的模式,它就不会是一个“队列”。

现在,如果处理无法足够快地处理的实时数据,则会遇到不同的问题。在这种情况下,您可能希望将输入的捕获与处理分离,并决定如何处理它。例如。例如,如果您无法跟上视频的实时处理,您还有一个选择。要么开始丢帧,要么异步/稍后处理数据。您只需决定什么最适合您的用例。我们无法抽象地回答这个问题。

关于ios - 大中央调度 : What happens when queues get overloaded?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63569923/

相关文章:

ios - 使用 dispatch_async 时的 EXC_BAD_ACCESS

ios - Swift,从字符串中获取变量名

ios - Swift URL.path 更改 utf-8 字符的编码

swift - 如何使用字符串键和 NSManagedObjects 数组作为值来限制对字典的扩展

ios - webview 在 swift 3 中打开 native fb 应用程序?

swift - swift 中 DispatchQueue 类型之间的区别

objective-c - 在dispatch_sync之前需要检查一个线程是否是主线程是什么?

ios - 自定义操作表

ios - 无法从 podfile 更新 firebase 最新框架

iPhone:单击透明 UIScrollView 后面的 View