Grand Central Dispatch


Grand Central Dispatch, is a technology developed by Apple Inc. to optimize application support for systems with multi-core processors and other symmetric multiprocessing systems. It is an implementation of task parallelism based on the thread pool pattern. The fundamental idea is to move the management of the thread pool out of the hands of the developer, and closer to the operating system. The developer injects "work packages" into the pool oblivious of the pool's architecture. This model improves simplicity, portability and performance.
GCD was first released with Mac OS X 10.6, and is also available with iOS 4 and above. The name "Grand Central Dispatch" is a reference to Grand Central Terminal.
The source code for the library that provides the implementation of GCD's services, libdispatch, was released by Apple under the Apache License on September 10, 2009. It has been ported to the FreeBSD 8.1+, MidnightBSD 0.3+, Linux, and Solaris. Attempts in 2011 to make libdispatch work on Windows were not merged into upstream. Apple has its own port of libdispatch.dll for Windows shipped with Safari and iTunes, but no SDK is provided.
Since around 2017, the original libdispatch repository hosted by Nick Hutchinson was deprecated in favor of a version that is part of the Swift core library created in June 2016. The new version supports more platforms, notably including Windows.

Design

GCD works by allowing specific tasks in a program that can be run in parallel to be queued up for execution and, depending on availability of processing resources, scheduling them to execute on any of the available processor cores .
A task can be expressed either as a function or as a "block." Blocks are an extension to the syntax of C, C++, and Objective-C programming languages that encapsulate code and data into a single object in a way similar to a closure. GCD can still be used in environments where blocks are not available.
Grand Central Dispatch still uses threads at the low level but abstracts them away from the programmer, who will not need to be concerned with as many details. Tasks in GCD are lightweight to create and queue; Apple states that 15 instructions are required to queue up a work unit in GCD, while creating a traditional thread could easily require several hundred instructions.
A task in Grand Central Dispatch can be used either to create a work item that is placed in a queue or assign it to an event source. If a task is assigned to an event source, then a work unit is made from the block or function when the event triggers, and the work unit is placed in an appropriate queue. This is described by Apple as more efficient than creating a thread whose sole purpose is to wait on a single event triggering.

Features

The dispatch framework declares several data types and functions to create and manipulate them:
Libdispatch comes with its own object model, OS Object, that is partially compatible with the Objective-C model. As a result, its objects can be bridged toll-free to ObjC objects.

Examples

Two examples that demonstrate the use of Grand Central Dispatch can be found in John Siracusa's Ars Technica Snow Leopard review. Initially, a document-based application has a method called analyzeDocument which may do something like count the number of words and paragraphs in the document. Normally, this would be a quick process, and may be executed in the main thread without the user noticing a delay between pressing a button and the results showing.

- analyzeDocument:sender

If the document is large and analysis takes a long time to execute then the main thread will wait for the function to finish. If it takes long enough, the user will notice, and the application may even "beachball". The solution can be seen here:

- analyzeDocument:sender

Here, the call to is placed inside a Block, which is then placed on one of the global concurrent queues. After it has finished running , a new block is placed on the main queue, which updates the GUI. By making these two small changes, the developer has avoided a potential stall of the application as seen by the user, and allowed their application to make better use of hardware resources.
The second example is that of parallelising a for loop:

for
total = summarize;

This code runs the do_work function count times, assigning the ith result to the ith element in the array results, and then calls summarize on array once the loop has ended. Unfortunately the work is computed sequentially, where it may not need to be. Assuming that do_work doesn't rely on the results of any of the other calls made to it, there is no reason why these calls cannot be made concurrently. This is how this would be done in GCD:

dispatch_apply, ^);
total = summarize;

Here, dispatch_apply runs the block passed to it, count times, placing each invocation on a global queue, and passing each block invocation a different number from 0 to count-1. This will allow the OS to spread out the work as it sees fit, choosing the optimal number of threads to run on for the current hardware and system load. dispatch_apply does not return until all the blocks it places on the given queue have completed execution, so that it can be guaranteed that all the work inside the original loop has completed before calling summarize.
Programmers can create their own serial queues for tasks which they know must run serially but which may be executed on a separate thread. A new queue would be created like so:

dispatch_queue_t exampleQueue;
exampleQueue = dispatch_queue_create;
// exampleQueue may be used here.
dispatch_release;

Care must be taken to avoid a dispatched block on a queue synchronously placing another block on the same queue as this is guaranteed to deadlock. Such code might do the following:

dispatch_queue_t exampleQueue = dispatch_queue_create;
dispatch_sync;
dispatch_release;

Applications

GCD is used throughout macOS, and Apple has encouraged its adoption by macOS application developers. FreeBSD developer Robert Watson announced the first adaptation of a major open source application, the Apache HTTP Server, to use GCD via the Apache GCD MPM on May 11, 2010, in order to illustrate the programming model and how to integrate GCD into existing, large-scale multi-threaded, applications. His announcement observed that the GCD MPM had one third to half the number of lines as other threaded MPMs.

Internals

GCD is implemented by libdispatch, with support from pthreads non-POSIX extensions developed by Apple. Apple has changed the interface since its inception through the official launch of GCD, Mountain Lion and recently Mavericks. The latest changes involve making the code supporting pthreads, both in user mode and kernel, private.
One other systems, libdispatch implements its own workqueue using the system's own event facilities. On macOS, kevent is used with the kernel workqueue.