简体   繁体   English

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

[英]iOS GCD: Difference between any global queue and the one with background priority (DISPATCH_QUEUE_PRIORITY_BACKGROUND)?

I am reading Concurrency Programming Guide and things confuse me. 我正在阅读《 并发编程指南》 ,这使我感到困惑。

I see a lot of code invoking the following for any background task: 对于任何后台任务,我看到很多代码调用以下代码:

dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

Now what I mean by 'background' is the popular meaning: 现在,我所说的“背景”是流行的意思:

Something that gets executed anywhere other than the main (UI) thread 除了主(UI)线程之外的任何地方都可以执行的东西

So following the docs, the above statement returns any non-main-thread queue with differing priorities. 因此在文档之后,以上语句将返回优先级不同的所有非主线程队列。

My question is - why does then DISPATCH_QUEUE_PRIORITY_BACKGROUND exist? 我的问题是-为什么DISPATCH_QUEUE_PRIORITY_BACKGROUND存在? Lately I also see many async tasks using DISPATCH_QUEUE_PRIORITY_BACKGROUND specifically to perform background tasks. 最近,我还看到了许多使用DISPATCH_QUEUE_PRIORITY_BACKGROUND专门执行后台任务的异步任务。

Aren't queues returned with DISPATCH_QUEUE_PRIORITY_DEFAULT , DISPATCH_QUEUE_PRIORITY_LOW or DISPATCH_QUEUE_PRIORITY_HIGH run very much away from main thread, if they are being returned using dispatch_get_global_queue ? 如果返回的队列是使用dispatch_get_global_queue返回的,则返回DISPATCH_QUEUE_PRIORITY_DEFAULTDISPATCH_QUEUE_PRIORITY_LOWDISPATCH_QUEUE_PRIORITY_HIGH队列是否与主线程的距离很远?

Aren't they background queues? 他们不是后台队列吗? What specific purpose does a queue returned with DISPATCH_QUEUE_PRIORITY_BACKGROUND serve? 使用DISPATCH_QUEUE_PRIORITY_BACKGROUND返回的队列有什么特定目的? I already referred to this but it does not clarify much, other than the popular meaning I mentioned above. 我已经提到了这一点,但是除了我上面提到的流行含义之外,它并没有太多说明。

I am sure I am pretty confused with words - background and background queues. 我确定我对单词-背景和背景队列感到很困惑。 If someone can explain (better, graphically) - will be a great help. 如果有人可以解释(更好,以图形方式),将会有很大帮助。

This is explained pretty well in the dispatch/queue.h header: 在dispatch / queue.h标头中对此进行了很好的解释:

DISPATCH_QUEUE_PRIORITY_HIGH Items dispatched to the queue will run at high priority, ie the queue will be scheduled for execution before any default priority or low priority queue. DISPATCH_QUEUE_PRIORITY_HIGH调度到队列的项目将以高优先级运行,即,将调度队列在任何默认优先级或低优先级队列之前执行。

DISPATCH_QUEUE_PRIORITY_DEFAULT Items dispatched to the queue will run at the default priority, ie the queue will be scheduled for execution after all high priority queues have been scheduled, but before any low priority queues have been scheduled. DISPATCH_QUEUE_PRIORITY_DEFAULT调度到队列的项目将以默认优先级运行,即,将在所有高优先级队列都已调度之后,但在任何低优先级队列都已调度之前,调度该队列执行。

DISPATCH_QUEUE_PRIORITY_LOW Items dispatched to the queue will run at low priority, ie the queue will be scheduled for execution after all default priority and high priority queues have been scheduled. DISPATCH_QUEUE_PRIORITY_LOW调度到队列的项目将以低优先级运行,即,将在调度所有默认优先级和高优先级队列之后调度该队列的执行。

DISPATCH_QUEUE_PRIORITY_BACKGROUND Items dispatched to the queue will run at background priority, ie the queue will be scheduled for execution after all higher priority queues have been scheduled and the system will run items on this queue on a thread with background status as per setpriority(2) (ie disk I/O is throttled and the thread's scheduling priority is set to lowest value). DISPATCH_QUEUE_PRIORITY_BACKGROUND调度到队列的项目将以后台优先级运行,即,在所有更高优先级的队列都已调度之后,队列将被安排执行,并且系统将根据setpriority(2)在后台状态下的线程上运行此队列中的项目(例如,磁盘I / O被限制并且线程的调度优先级被设置为最低值。

And keep in mind this is a global queue. 请记住,这是一个全局队列。 Other things, like system frameworks, may be scheduling in to it. 诸如系统框架之类的其他事物也可能正在计划之中。 It's very easy to starve the priority bands - if there are a lot of DISPATCH_QUEUE_PRIORITY_HIGH tasks being scheduled, tasks at the default priority may have to wait quite a while before executing. 耗尽优先级频段非常容易-如果调度了很多DISPATCH_QUEUE_PRIORITY_HIGH任务,则默认优先级的任务可能需要等待一段时间才能执行。 And tasks in DISPATCH_QUEUE_PRIORITY_BACKGROUND may have to wait a very long time, as all other priorities above them must be empty. 并且DISPATCH_QUEUE_PRIORITY_BACKGROUND中的任务可能必须等待长时间,因为它们上方的所有其他优先级必须为空。

A lot of developers abuse the global concurrent queue. 许多开发人员滥用全局并发队列。 They want a execute a block, need a queue, and just use that at the default priority. 他们想要执行一个块,需要一个队列,并以默认优先级使用它。 That kind of practice can lead to some very difficult to troubleshoot bugs. 这种做法可能会导致很难解决错误。 The global concurrent queue is a shared resource and should be treated with care. 全局并发队列是共享资源,应谨慎对待。 In most cases it makes more sense to create a private queue. 在大多数情况下,创建专用队列更有意义。

A concurrent queue is not asynchronous, it is concurrent. 并发队列不是异步的,而是并发的。 Synchronous tasks can still be scheduled into it, and they will still execute synchronously. 仍然可以将同步任务安排在其中,并且它们仍将同步执行。 Concurrent queues, like serial queues, dequeue in FIFO order. 并发队列(如串行队列)按FIFO顺序出队。 They execute blocks concurrently, unlike serial queues. 它们与串行队列不同,可同时执行块。 Concurrent and asynchronous are not the same thing. 并发和异步不是同一回事。

Also keep in mind that if the main thread is idle, a concurrent queue can re-use that thread - and in fact will prefer doing that to creating new threads. 还请记住,如果主线程处于空闲状态,并发队列可以重用该线程-实际上,与创建新线程相比,它更愿意这样做。 Using a concurrent queue will not guarantee you will not block the user interface: 使用并发队列不能保证您不会阻塞用户界面:

Blocks submitted to these dispatch queues are invoked on a pool of threads fully managed by the system. 提交给这些调度队列的块在系统完全管理的线程池上调用。 No guarantee is made regarding which thread a block will be invoked on; 无法保证将在哪个线程上调用块。 however, it is guaranteed that only one block submitted to the FIFO dispatch queue will be invoked at a time. 但是,可以保证一次只提交一个提交给FIFO分派队列的块。

GCD makes no guarantees about what thread will be used to execute a block on a concurrent queue. GCD不保证将使用哪个线程在并发队列上执行块。 If you use the main queue, the block will be executed serially on the main thread. 如果使用主队列,则该块将在主线程上顺序执行。 A concurrent queue can use any thread, and as an optimization will prefer to use existing threads. 并发队列可以使用任何线程,并且作为优化,它倾向于使用现有线程。 It will only create a new thread if no threads are available to be reused. 仅当没有可用线程重用时,它才会创建一个新线程。 And in fact the main thread is often it's first choice (if the main thread is available for work) because it is "warm". 实际上,主线程通常是首选(如果主线程可用于工作),因为它是“温暖的”。

To reiterate: With Grand Central Dispatch you can be certain that a task will execute on the main thread (by submitting to the main queue). 重申一下:使用Grand Central Dispatch,您可以确定任务将在主线程上执行(通过提交到主队列)。 You cannot be certain that a task will not execute on the main thread. 您不能确定任务不会在主线程上执行。

If you have many background tasks, the CPU or CPUs of your device will be shared between all of them. 如果您有许多后台任务,则设备中的一个或多个CPU将在所有这些任务之间共享。 Most of the time that is the right thing to do. 在大多数情况下,这样做是正确的。 If a task takes too long to finish, you solve the problem by trying to make it more efficient. 如果任务完成的时间太长,则可以通过提高效率来解决问题。

In very rare cases, you may have a task that takes a long time, but it is Ok to wait for it. 在极少数情况下,您可能需要花费很长时间来完成任务,但是可以等待它。 So you give it BACKGROUND priority. 因此,您将其作为背景优先级。 If there is any work to do at NORMAL priority, that work will be done first, and only when there is a spare CPU doing nothing else, the BACKGROUND task will be performed. 如果有任何工作要以“正常”优先级进行,则将首先完成该工作,并且仅当有备用CPU做其他事情时,才会执行Background任务。 And there is the queue with HIGH priority; 并且存在具有高优先级的队列; tasks in that queue will be executed first; 该队列中的任务将首先执行; you would do that if one specific task needs to be finished as quick as possible even if it means that other tasks are delayed . 如果一个特定的任务需要尽快完成, 即使这意味着其他任务被延迟了,您也会这样做。

From a point of view of your programming logic, all three queues are identical. 从编程逻辑的角度来看,所有三个队列都是相同的。 It just affects which tasks the OS tries to finish first, and which it doesn't care about that much. 它只会影响OS首先尝试完成的任务,而对它的影响并不大。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 iOS GCD:DISPATCH_QUEUE_PRIORITY_BACKGROUND,文件中“磁盘I / O被限制”是什么意思? - iOS GCD: DISPATCH_QUEUE_PRIORITY_BACKGROUND, what does “disk I/O is throttled” mean in document? 检查DISPATCH_QUEUE_PRIORITY_BACKGROUND是否存在的最佳做法? - Best practice for checking if DISPATCH_QUEUE_PRIORITY_BACKGROUND exists? 为什么在使用DISPATCH_QUEUE_PRIORITY_BACKGROUND时dispatch_sync在主线程上进行工作? - Why is dispatch_sync doing work on the main thread when it uses DISPATCH_QUEUE_PRIORITY_BACKGROUND? Dispatch Queue 中的 Dispatch Queue Priority 和 QoS 有什么区别? - What is difference between Dispatch Queue Priority and QoS in Dispatch Queue? GCD DISPATCH_QUEUE_SERIAL它将运行什么优先级? - GCD DISPATCH_QUEUE_SERIAL what priority is it going to run on? GCD-dispatch_async在主队列上工作,但在后台队列上崩溃 - GCD - dispatch_async works on main queue but crashes on a background queue GCD dispatch_async DISPATCH_QUEUE_PRIORITY_DEFAULT EXC_BAD_ACCESS崩溃 - GCD dispatch_async DISPATCH_QUEUE_PRIORITY_DEFAULT EXC_BAD_ACCESS crash GCD 中的“全局队列”和“主队列”有什么区别? - What's the difference between the “global queue” and the “main queue” in GCD? GCD并发队列具有相同优先级的操作? - GCD concurrent queue with operations of same priority? 如何修改自定义GCD队列的优先级? - How to modify the priority of a custom GCD queue?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM