What is the difference between dispatch_get_global_queue and dispatch_queue_create? What is the difference between dispatch_get_global_queue and dispatch_queue_create? multithreading multithreading

What is the difference between dispatch_get_global_queue and dispatch_queue_create?


As the documentation describes, a global queue is good for concurrent tasks (i.e. you're going to dispatch various tasks asynchronously and you're perfectly happy if they run concurrently) and if you don't want to encounter the theoretical overhead of creating and destroying your own queue.

The creating of your own queue is very useful if you need a serial queue (i.e. you need the dispatched blocks to be executed one at a time). This can be useful in many scenarios, such as when each task is dependent upon the preceding one or when coordinating interaction with some shared resource from multiple threads.

Less common, but you will also want to create your own queue if you need to use barriers in conjunction with a concurrent queue. In that scenario, create a concurrent queue (i.e. dispatch_queue_create with the DISPATCH_QUEUE_CONCURRENT option) and use the barriers in conjunction with that queue. You should never use barriers on global queues.

My general counsel is if you need a serial queue (or need to use barriers), then create a queue. If you don't, go ahead and use the global queue and bypass the overhead of creating your own.


If you want a concurrent queue, but want to control how many operations can run concurrently, you can also consider using NSOperationQueue which has a maxConcurrentOperationCount property. This can be useful when doing network operations and you don't want too many concurrent requests being submitted to your server.


Just posted in a different answer, but here is something I wrote quite a while back:

The best way to conceptualize queues is to first realize that at the very low-level, there are only two types of queues: serial and concurrent.

Serial queues are monogamous, but uncommitted. If you give a bunch of tasks to each serial queue, it will run them one at a time, using only one thread at a time. The uncommitted aspect is that serial queues may switch to a different thread between tasks. Serial queues always wait for a task to finish before going to the next one. Thus tasks are completed in FIFO order. You can make as many serial queues as you need with dispatch_queue_create.

The main queue is a special serial queue. Unlike other serial queues, which are uncommitted, in that they are "dating" many threads but only one at time, the main queue is "married" to the main thread and all tasks are performed on it. Jobs on the main queue need to behave nicely with the runloop so that small operations don't block the UI and other important bits. Like all serial queues, tasks are completed in FIFO order.

If serial queues are monogamous, then concurrent queues are promiscuous. They will submit tasks to any available thread or even make new threads depending on system load. They may perform multiple tasks simultaneously on different threads. It's important that tasks submitted to the global queue are thread-safe and minimize side-effects. Tasks are submitted for execution in FIFO order, but order of completion is not guaranteed. As of this writing, there are only three concurrent queues and you can't make them, you can only fetch them with dispatch_get_global_queue.

edit: blog post expanding on this answer: http://amattn.com/p/grand_central_dispatch_gcd_summary_syntax_best_practices.html


One returns the existing global queue, the other creates a new one. Instead of using GCD, I would consider using NSOperation and operation queue. You can find more information about it in this guide. Typically, of you want the operations to execute concurrently, you want to create your own queue and put your operations in it.