我正在阅读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_LOW
,DISPATCH_QUEUE_PRIORITY_HIGH
或dispatch_get_global_queue
返回的Aren队列与主线程相距甚远?
Aren他们的背景队列?使用DISPATCH_QUEUE_PRIORITY_BACKGROUND
返回的队列有什么特定用途?我已经referred to this了,但除了我上面提到的流行意义之外,它没有说明多少。
我确信我对语言很困惑 - 背景和背景队列。如果有人可以解释(更好,图形化) - 将会是一个很大的帮助。
答案 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任务。并且存在具有高优先级的队列;该队列中的任务将首先执行;如果一个特定任务需要尽快完成,即使这意味着其他任务被延迟,你也会这样做。
从编程逻辑的角度来看,所有三个队列都是相同的。它只影响操作系统首先尝试完成哪些任务,以及它不关心那么多。