Grand Central Dispatch: Threads vs Queues, Sync vs Async, Serial vs Concurrent

Avinash
Mac O’Clock
Published in
3 min readApr 4, 2020

--

Grand Central Dispatch or GCD is a framework built by Apple to allow for concurrent execution of code. It abstracts a lot of painful and tedious code necessary to smoothly do parallel computation.

I have seen many stack-overflow questions over the terms in the title of the article and caused serious confusion when I tried to understand GCD. So we will first take a look at some of the key terms necessary to fully understand GCD. And then we will see the code to use GCD in the most basic way.

Common Terms

Tasks are just blocks of code we want to execute.

Queues are to-do-lists i.e they are a list of tasks. By nature of queues they additionally promise us that the tasks will be taken care of in a linear fashion (first in first out).

There are two types of queues — serial and concurrent. The tasks in serial queues are executed one by one i.e the first task has to be completed before the start of the second task. The tasks in concurrent queues are done in parallel. The amount of parallelism depends on the available hardware.

Threads are workers that do tasks. These tasks are provided by queues.

Now the brilliance of GCD lies in the fact that we don’t have to worry about the interaction between threads and queues i.e we don’t have to state which thread performs which task from which queue. This is taken care of by the OS optimising for efficient resource (hardware) usage.

As a vague analogue, think of GCD like a job fair. Threads are people looking for work. Queues are companies that have jobs to be done. GCD facilitates that the jobs these companies have are optimally assigned to the people looking for work i.e. the tasks in the queues are optimally assigned to threads.

While adding a task to a queue, it can be made to run either synchronously (sync) or asynchronously (async). When an async task is taken up by a thread it is put on hold to be done later or delegated to another thread while the current thread continues to work on the remaining sync tasks. This leads to the common terminology that sync tasks are blocking and async tasks are non-blocking.

How does this all translate into code?

The only way GCD is exposed to programmers is through queues. You can create your own queues or re-use global queues.

// creating your own queue
let myOwnQueue = DispatchQueue(label: "com.appname.queuename")

There are 4 types of global queues namely user interactive, user initiated, utility, background stated in the decreasing order of priority. It is advised not to create many queues and to re-use global queues in your applications. There is also a main queue which is the default queue that all your code is added to. Any view updates needs to be done on the main queue.

// re-using global queues
let globalQueue = DispatchQueue.global(QoS: .userInitiated)

To add tasks to a queue we call the sync or async method (depending on the task nature) on the queue to which we want to add the task to.

// adding an async task to a background queuelet backgroundQueue = DispatchQueue.global(QoS: .background)
backgroundQueue.async {
// some time taking task like downloading video from internet
}

For more code examples and deeper understanding, you can refer to these wonderful articles below.

https://www.appcoda.com/grand-central-dispatch/

--

--

Avinash
Mac O’Clock

Interested in ML & Software. Prev at Inito, ShareChat. Ola. Graduated from IIT Madras.