Grand Central Dispatch:队列超载时会发生什么?
Grand Central Dispatch: What happens when queues get overloaded?
我在 GCD 的文档或教程中没有找到的一个非常简单的问题:如果我将工作提交到队列的速度快于它被处理和删除的速度,会发生什么情况?我知道 GCD 队列没有大小限制,会一直工作直到程序内存不足吗?有什么办法可以妥善处理这种情况吗?
What happens if I'm submitting work to queues faster than it's being processed and removed?
视情况而定。
如果将任务分派到single/shared串行队列,它们只会被添加到队列中,并以先进先出的方式处理它们。没问题。内存是您唯一的限制。
但是,如果将任务分派到并发队列,最终会出现“线程爆炸”,并且您将很快耗尽可用于该 quality-of-service(QoS ).如果 OS 需要利用具有相同 QoS 的队列,这可能会导致不可预测的行为。因此,您必须非常小心,避免这种线程爆炸。
查看关于线程爆炸的讨论 WWDC 2015 Building Responsive and Efficient Apps with GCD and again in WWDC 2016 Concurrent Programming With GCD in Swift 3。
Is there any way to properly handle this situation?
很难抽象地回答这个问题。不同的情况需要不同的解决方案。
在线程爆炸的情况下,解决方案是使用concurrentPerform
来限制并发度(将并发限制为您设备上的核心数)。或者我们使用操作队列及其 maxConcurrentOperationCount
将并发程度限制在合理的范围内。也有其他模式,但想法是将并发限制为适合相关设备的模式。
但是,如果您只是将大量任务分派到串行队列,那么您无能为力(除了寻找并行机会,以有效利用所有 CPU's核心)。但这没关系,因为这就是队列的全部目的,让它按照提交的顺序执行任务,即使队列跟不上也是如此。如果它不遵循这种 FIFO 模式,它就不会是一个“队列”。
现在,如果处理 real-time 无法足够快地处理的数据,您就会遇到不同的问题。在这种情况下,您可能希望将输入的捕获与处理分离,并决定如何处理它。例如。例如,如果您跟不上 real-time 视频处理,您可以选择。您要么开始丢帧,要么处理数据 asynchronously/later。您只需要决定什么适合您的用例。我们无法抽象地回答这个问题。
我在 GCD 的文档或教程中没有找到的一个非常简单的问题:如果我将工作提交到队列的速度快于它被处理和删除的速度,会发生什么情况?我知道 GCD 队列没有大小限制,会一直工作直到程序内存不足吗?有什么办法可以妥善处理这种情况吗?
What happens if I'm submitting work to queues faster than it's being processed and removed?
视情况而定。
如果将任务分派到single/shared串行队列,它们只会被添加到队列中,并以先进先出的方式处理它们。没问题。内存是您唯一的限制。
但是,如果将任务分派到并发队列,最终会出现“线程爆炸”,并且您将很快耗尽可用于该 quality-of-service(QoS ).如果 OS 需要利用具有相同 QoS 的队列,这可能会导致不可预测的行为。因此,您必须非常小心,避免这种线程爆炸。
查看关于线程爆炸的讨论 WWDC 2015 Building Responsive and Efficient Apps with GCD and again in WWDC 2016 Concurrent Programming With GCD in Swift 3。
Is there any way to properly handle this situation?
很难抽象地回答这个问题。不同的情况需要不同的解决方案。
在线程爆炸的情况下,解决方案是使用concurrentPerform
来限制并发度(将并发限制为您设备上的核心数)。或者我们使用操作队列及其 maxConcurrentOperationCount
将并发程度限制在合理的范围内。也有其他模式,但想法是将并发限制为适合相关设备的模式。
但是,如果您只是将大量任务分派到串行队列,那么您无能为力(除了寻找并行机会,以有效利用所有 CPU's核心)。但这没关系,因为这就是队列的全部目的,让它按照提交的顺序执行任务,即使队列跟不上也是如此。如果它不遵循这种 FIFO 模式,它就不会是一个“队列”。
现在,如果处理 real-time 无法足够快地处理的数据,您就会遇到不同的问题。在这种情况下,您可能希望将输入的捕获与处理分离,并决定如何处理它。例如。例如,如果您跟不上 real-time 视频处理,您可以选择。您要么开始丢帧,要么处理数据 asynchronously/later。您只需要决定什么适合您的用例。我们无法抽象地回答这个问题。