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

我正在阅读并发编程指南和东西混淆了我。

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

dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 

现在我所说的“背景”是stream行的意思:

除了主(UI)线程之外的任何地方执行的东西

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

我的问题是 – 为什么然后DISPATCH_QUEUE_PRIORITY_BACKGROUND存在? 最近我还看到许多使用DISPATCH_QUEUE_PRIORITY_BACKGROUNDasynchronous任务来执行后台任务。

DISPATCH_QUEUE_PRIORITY_DEFAULTDISPATCH_QUEUE_PRIORITY_LOWDISPATCH_QUEUE_PRIORITY_HIGH返回的队列是否与主线程相距甚远,如果使用dispatch_get_global_queue返回?

他们不是背景排队吗? 用DISPATCH_QUEUE_PRIORITY_BACKGROUND返回的队列有什么具体的用途? 我已经提到了这个,但是除了上面提到的stream行的含义之外,它没有多less澄清。

我相信我很迷茫的话 – 背景和背景排队。 如果有人可以解释(更好,graphics) – 将是一个很大的帮助。

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

在极less数情况下,您可能需要花费很长时间才能完成任务,但等待它的时间还是可以的。 所以你给它的背景优先。 如果在NORMAL优先级下有任何工作要做,那么这项工作将首先完成,只有当有空闲的CPU什么都不做时,才会执行BACKGROUND任务。 有高优先级的队列; 该队列中的任务将首先执行; 如果某个特定的任务需要尽可能快地完成, 即使这意味着其他任务被延迟,也会这样做。

从编程逻辑的angular度来看,所有三个队列是相同的。 它只影响操作系统首先完成哪些任务,哪些不关心。

这在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中的任务可能需要等待长时间,因为所有其他优先级必须为空。

很多开发者滥用全局并发队列。 他们想要一个块执行,需要一个队列,并使用默认的优先级。 这种做法可能会导致一些很难排除错误的问题。 全局并发队列是一个共享资源,应该小心处理。 在大多数情况下,创build一个私有队列更有意义。

并发队列不是asynchronous的,它是并发的。 同步任务仍然可以调度到它,他们仍然会同步执行。 并发队列,如串行队列,按FIFO顺序出队。 它们不像串行队列那样同时执行块。 并发和asynchronous并不是一回事。

另外请记住,如果主线程空闲,并发队列可以重用该线程 – 事实上会更喜欢这样做来创build新的线程。 使用并发队列不能保证你不会阻塞用户界面:

提交给这些分派队列的块在由系统完全pipe理的线程池上被调用。 不能保证块将被调用的线程。 但是,一次只能调用一个提交给FIFO调度队列的数据块。

GCD不保证将使用哪个线程来执行并发队列上的块。 如果使用主队列,则该块将在主线程上串行执行。 一个并发队列可以使用任何线程,而优化会更喜欢使用现有的线程。 它只会创build一个新的线程,如果没有线程可用于重用。 事实上,主线程往往是首选(如果主线程可用于工作),因为它是“温暖的”。

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