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

Nir*_*att 36 concurrency cocoa multithreading grand-central-dispatch ios

我正在阅读并发编程指南,事情让我很困惑.

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

dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
Run Code Online (Sandbox Code Playgroud)

现在我所说的'背景'是流行的含义:

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

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

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

如果返回使用队列DISPATCH_QUEUE_PRIORITY_DEFAULT,是不是返回队列,DISPATCH_QUEUE_PRIORITY_LOW或者DISPATCH_QUEUE_PRIORITY_HIGH远离主线程运行dispatch_get_global_queue

他们不是背景队列吗?队列返回的具体目的是什么DISPATCH_QUEUE_PRIORITY_BACKGROUND?我已经提到了这一点,但除了我上面提到的流行意义之外,它没有说明多少.

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

que*_*ish 37

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

DISPATCH_QUEUE_PRIORITY_HIGH分派给队列的项目将以高优先级运行,即队列将被调度为在任何默认优先级或低优先级队列之前执行.

DISPATCH_QUEUE_PRIORITY_DEFAULT调度到队列的项目将以默认优先级运行,即在调度所有高优先级队列之后但在调度任何低优先级队列之前,将调度队列执行.

DISPATCH_QUEUE_PRIORITY_LOW调度到队列的项目将以低优先级运行,即在调度所有默认优先级和高优先级队列后,将调度队列以执行.

DISPATCH_QUEUE_PRIORITY_BACKGROUND调度到队列的项目将以后台优先级运行,即在调度所有优先级较高的队列后,队列将被调度执行,系统将根据setpriority(2)在具有后台状态的线程上运行此队列中的项目(2)(即磁盘I/O被限制,线程的调度优先级设置为最低值.

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

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

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

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

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

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

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

  • 不,除了来自主线程的`dispatch_sync`之外,GCD永远不会在未提交到主队列的主线程上或针对主队列的队列上运行任何内容. (6认同)
  • 我很抱歉,但你错了,主线程runloop(即UIApplicationMain)排出主队列的方式与调用`dispatch_main`时使用的机制不同,而前者主线程不可供任何人使用除主队列之外的队列或以主队列为目标的队列(直接或间接). (2认同)

gna*_*729 14

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

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

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