What is the difference between dispatch_get_global_queue and dispatch_queue_create?

24,521

Solution 1

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.

Solution 2

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

Share:
24,521
Nosrettap
Author by

Nosrettap

I recently graduated from Duke University as a computer science and economics double major. I am now working full time as a software developer. I am proficient in Objective-C and Java, and I know (to some degree) C, C++, Python, Perl, SML, Assembly, HTML, CSS, JavaScript.

Updated on July 09, 2022

Comments

  • Nosrettap
    Nosrettap almost 2 years

    I'm writing a moderately complex iOS program that needs to have multiple threads for some of its longer operations (parsing, connections to the network...etc). However, I'm confused as to what the difference is between dispatch_get_global_queue and dispatch_queue_create.

    Which one should I use and could you give me a simple explanation of what the difference is in general? Thanks.

  • Rob
    Rob almost 12 years
    Just to clarify, if you're creating a dispatch queue, it's serial. If you're using the global dispatch queue, it can be concurrent (but not guaranteed to be so). I assume your counsel re creating queues for concurrency is related to operation queues, not dispatch queues. (I know you know that, but I just wanted to make sure readers weren't confused.)
  • Max Yankov
    Max Yankov almost 12 years
    Yes, I'm talking about operation queues. I was facing the same problem some time ago, and when I created my own operation queue without any further configuration, operations added in it were executed concurrently to one another.
  • jscs
    jscs almost 12 years
    Though note that in Lion it's now possible to get a concurrent queue from dispatch_queue_create() by passing DISPATCH_QUEUE_CONCURRENT. It's not specified (and probably doesn't matter) whether this will just return one of the existing global queues.
  • jscs
    jscs almost 12 years
    I should have added, "presumably that functionality will be coming to iOS eventually".
  • user523234
    user523234 almost 12 years
    Upvoted for correctly pointed out the differences in term of concurrent and serial queues.
  • jscs
    jscs over 11 years
    A small note in reply to my own comment above: the DISPATCH_QUEUE_CONCURRENT must, in fact, create a new queue, because it's possible to use dispatch barriers on such a queue, which is not allowed with the global queues.
  • bradley.ayers
    bradley.ayers over 10 years
    The blog post link is dead.
  • amattn
    amattn about 10 years
    Still seems to work for me. I did recently update blog engines, so there is a new canonical address here: amattn.com/p/…
  • Guy
    Guy over 9 years
    and wrong... From my experience, this answer is not accurate. User queue can be created (and function) as a concurrent queue. @PaulRobinson
  • Carl Smith
    Carl Smith almost 9 years
    From Apple's dispatch_queue_create documentation: In OS X v10.7 and later or iOS 4.3 and later, specify DISPATCH_QUEUE_SERIAL (or NULL) to create a serial queue or specify DISPATCH_QUEUE_CONCURRENT to create a concurrent queue. In earlier versions, you must specify NULL for this parameter.
  • mfaani
    mfaani over 7 years
    About the diff of 'mainQueue vs. anyOthercreatedSerialQueue'. While both are serial, mainQueue is to be used for UI related tasks or basically anything important that is to be returned immediately( though I can't think of something good now). But anyOthercreatedSerialQueue is to be used for special serialization of something you might have to do in a background thread such as writing to an array as you already presented in your answer here