iOS GCD:任何全局队列和具有后台优先级的队列(DISPATCH_QUEUE_PRIORITY_BACKGROUND)之间的差异?

时间:2014-07-31 07:00:39

标签: ios multithreading cocoa concurrency grand-central-dispatch

我正在阅读Concurrency Programming Guide,事情使我感到困惑。

我看到很多代码为任何后台任务调用以下内容:

dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

现在我的意思是'背景'是流行的意思:

在主(UI)线程以外的任何地方执行的操作

因此,遵循文档,上面的语句将返回任何具有不同优先级的非主线程队列。

我的问题是 - 为什么DISPATCH_QUEUE_PRIORITY_BACKGROUND存在? 最近我还看到许多使用DISPATCH_QUEUE_PRIORITY_BACKGROUND专门执行后台任务的异步任务。

如果使用DISPATCH_QUEUE_PRIORITY_DEFAULT返回,则DISPATCH_QUEUE_PRIORITY_LOWDISPATCH_QUEUE_PRIORITY_HIGHdispatch_get_global_queue返回的Aren队列与主线程相距甚远?

Aren他们的背景队列?使用DISPATCH_QUEUE_PRIORITY_BACKGROUND返回的队列有什么特定用途?我已经referred to this了,但除了我上面提到的流行意义之外,它没有说明多少。

我确信我对语言很困惑 - 背景和背景队列。如果有人可以解释(更好,图形化) - 将会是一个很大的帮助。

2 个答案:

答案 0 :(得分:37)

这在dispatch / queue.h标题中解释得很好:

  

DISPATCH_QUEUE_PRIORITY_HIGH   分派到队列的项目将以高优先级运行,   即,队列将被安排在之前执行   任何默认优先级或低优先级队列。

     

DISPATCH_QUEUE_PRIORITY_DEFAULT   分派给队列的项目将以默认值运行   优先级,即队列将被安排执行   在安排了所有高优先级队列之后,但是   在安排任何低优先级队列之前。

     

DISPATCH_QUEUE_PRIORITY_LOW   分派到队列的项目将以低优先级运行,   即,队列将被安排执行   默认优先级和高优先级队列   调度。

     

DISPATCH_QUEUE_PRIORITY_BACKGROUND   分派给队列的项目将以后台优先级运行,即队列   将在所有优先级较高的队列之后安排执行   已安排,系统将在一个线程上运行此队列中的项目   根据setpriority(2)的背景状态(即磁盘I / O被限制并且   线程的调度优先级设置为最低值。

请记住,这是一个全局队列。其他的东西,比如系统框架,可能正在调度它。让优先级频段匮乏非常容易 - 如果有很多DISPATCH_QUEUE_PRIORITY_HIGH任务被安排,那么默认优先级的任务可能需要等待一段时间才能执行。 DISPATCH_QUEUE_PRIORITY_BACKGROUND中的任务可能必须等待非常长时间,因为它们之上的所有其他优先级必须为空。

许多开发人员滥用全局并发队列。他们想要执行一个块,需要一个队列,然后只使用默认优先级。这种做法可能导致一些非常难以解决的错误。全局并发队列是共享资源,应小心处理。在大多数情况下,创建私有队列更有意义。

并发队列不是异步的,而是并发的。同步任务仍然可以安排到它中,它们仍然会同步执行。并发队列(如串行队列)按FIFO顺序出列。与串行队列不同,它们同时执行块。并发和异步不是一回事。

还要记住,如果主线程处于空闲状态,并发队列可以重用该线程 - 实际上更愿意这样做来创建新线程。使用并发队列不会保证您不会阻止用户界面:

  

在池上调用提交给这些调度队列的块   线程完全由系统管理。不保证   将调用哪个线程的块;但是,它只保证   提交到FIFO调度队列的一个块将一次被调用。

GCD不保证在并发队列上使用什么线程来执行块。如果使用主队列,则将在主线程上串行执行该块。并发队列可以使用任何线程,并且优化将优先使用现有线程。如果没有可用的线程可用,它只会创建一个新线程。事实上,主线程通常是它的第一选择(如果主线程可用于工作),因为它是“温暖的”。

重申: 使用Grand Central Dispatch,您可以确定任务将在主线程上执行(通过提交到主队列)。 您无法确定任务不会在主线程上执行。

答案 1 :(得分:14)

如果您有许多后台任务,则设备的CPU或CPU将在所有这些任务之间共享。大多数时候这是正确的事情。如果任务完成时间太长,您可以通过尝试提高效率来解决问题。

在极少数情况下,您可能需要花费很长时间的任务,但等待它是可以的。所以你给它优先考虑。如果在NORMAL优先级上有任何工作要做,那么将首先完成该工作,并且只有当备用CPU不执行任何其他操作时,才会执行BACKGROUND任务。并且存在具有高优先级的队列;该队列中的任务将首先执行;如果一个特定任务需要尽快完成,即使这意味着其他任务被延迟,你也会这样做。

从编程逻辑的角度来看,所有三个队列都是相同的。它只影响操作系统首先尝试完成哪些任务,以及它不关心那么多。