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

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


This is explained pretty well in the dispatch/queue.h header:

DISPATCH_QUEUE_PRIORITY_HIGH Items dispatched to the queue will run at high priority, i.e. the queue will be scheduled for execution before any default priority or low priority queue.

DISPATCH_QUEUE_PRIORITY_DEFAULT Items dispatched to the queue will run at the default priority, i.e. 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_LOW Items dispatched to the queue will run at low priority, i.e. the queue will be scheduled for execution after all default priority and high priority queues have been scheduled.

DISPATCH_QUEUE_PRIORITY_BACKGROUND Items dispatched to the queue will run at background priority, i.e. 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) (i.e. disk I/O is throttled and the thread's scheduling priority is set to lowest value).

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. And tasks in DISPATCH_QUEUE_PRIORITY_BACKGROUND may have to wait a very long time, as all other priorities above them must be empty.

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. 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.

GCD makes no guarantees about what thread will be used to execute a block on a concurrent queue. 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).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. 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. 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.