[Swift] Asynchronous processing "GCD"

What is GCD

GCD is a technology that facilitates asynchronous processing. GCD does asynchronous processing through queues and does not manage threads directly.

** The system is in charge of thread management The processing is automatically optimized in consideration of the number of CPU cores and the load status. ** **

That is, the number of parallel processes and scheduling, The programmer does not have to think about which process to perform in which thread.

Speaking of programmers, ** Just add the task to the queue. ** **

Threads are not created each time Tasks are assigned to vacant threads from the threads prepared in advance.

If there are no free threads at this time, You will have to wait until the thread is free.

This kind of management method is called ** thread pool **.

Implementation method

GCD queues are called dispatch queues. Dispatch queues are classified into two types according to the task execution method.

** · Serial dispatch queue -> Wait for the processing currently being executed to finish before executing the next processing -Parallel dispatch queue -> Execute the next process without waiting for the end of the process currently being executed **

Get Dispatch Queue

As an existing dispatch queue for GCD It also provides one main queue and multiple global queues.

The main queue is ** a serial dispatch queue that executes tasks on the main thread. ** **

To get the main queue, use the main class property.


import Dispatch

let queue = DispatchQueue.main   //Get main dispatch queue

Updating the user interface, that is, user operations, It is always running in the main queue.

To reflect the result of asynchronous processing executed in another dispatch queue You will get the main queue and add tasks.

Global queue refers to a parallel dispatch queue ** Get by specifying the execution priority. ** **

The execution priority is called ** QoS **, and there are the following five in descending order of priority.

① userInteractive For example, running an animation Used for processes that appear to freeze if not executed immediately

② userInitiated Used for processing that is executed in response to input from the user, such as when something is tapped

③ default Used when no QoS is specified

④ utility While accompanied by visual information updates Used for processing that does not require immediate results

⑤ background It is done in an invisible place such as backup, Used for processing that does not cause any problems even if it takes several minutes to several hours

Add task

To add a task to the retrieved dispatch queue Use the DispatchQueue type async (execute :) method.

The method for adding tasks is the same for both the serial dispatch queue and the parallel dispatch queue.

In the following sample code Call the async (execute :) method on the parallel dispatch queue This is the code that is performing asynchronous processing.

In addition to the for-in statement in the main thread, the for-in statement for asynchronous processing is also performed. Since the processing is done in parallel, the execution result will be confused.


import Foundation
import PlaygroundSupport

PlaygroundPage.current.needsIndefiniteExecution = true

let queue = DispatchQueue.global(qos: .userInitiated)
queue.async {
    for item in 0..<5 {
        print("Asynchronous processing:\(item)")
    }
}

for item in 0..<5 {
    print("Synchronous processing:\(item)")
}

Execution result
Synchronous processing:0
Asynchronous processing:0
Synchronous processing:1
Asynchronous processing:1
Synchronous processing:2
Asynchronous processing:2
Synchronous processing:3
Synchronous processing:4
Asynchronous processing:3
Asynchronous processing:4

The QoS this time was userInitiated, If you set this to userInteractive, the result will change again.


import Foundation
import PlaygroundSupport

PlaygroundPage.current.needsIndefiniteExecution = true

let queue = DispatchQueue.global(qos: .userInteractive)
queue.async {
    for item in 0..<5 {
        print("Asynchronous processing:\(item)")
    }
}

for item in 0..<5 {
    print("Synchronous processing:\(item)")
}

Execution result
Asynchronous processing:0
Synchronous processing:0
Asynchronous processing:1
Synchronous processing:1
Asynchronous processing:2
Asynchronous processing:3
Synchronous processing:2
Asynchronous processing:4
Synchronous processing:3
Synchronous processing:4

You can see that it has priority over userInitiated. The result will change a little, so ** When performing asynchronous processing, clarify the priority of parallel processing required at that time. ** **

When to use

When using GCD, it is ** a simple asynchronous processing implementation **. The reason is that tasks can be represented as closures.

Move the time-consuming process from the main thread to another thread Let's take an example of notifying the main thread when the process is completed.


import Foundation
import PlaygroundSupport

PlaygroundPage.current.needsIndefiniteExecution = true

let queue = DispatchQueue.global(qos: .userInteractive)
queue.async {
    print("Asynchronous processing execution-1")

    let queue = DispatchQueue.main
    queue.async {
        print("Main thread execution")
    }

    print("Asynchronous processing execution-2")
}

You can see that control has returned to the main thread since the asynchronous process was done. Such a simple asynchronous process can be easily realized.

** Conversely, defining dependencies between tasks and canceling tasks according to conditions, etc. Use the OperationQueue class, etc. ** **

This concludes the discussion of dispatch queues.

I think this is enough for simple asynchronous processing, Use the OperationQueue class etc. for complicated processing.

Thank you for watching until the end.

Recommended Posts

[Swift] Asynchronous processing "GCD"
[Swift] About asynchronous processing "Operation"
[Swift] What is asynchronous processing?
[Swift] Asynchronous processing using PromiseKit
[Swift] Implement swipe processing
Spring with Kotorin --6 Asynchronous processing
Asynchronous processing with Shoryuken + SQS
[Swift] Processing to share screenshots
Try implementing asynchronous processing in Azure
[Swift] "for-in statement" about iterative processing
Implementation of asynchronous processing in Tomcat
Basic basis of Android asynchronous processing "AsyncTask"
Asynchronous processing by RxJava (RxAndroid) on Android
[GCD] Basics of parallel programming in Swift
Implementation of multi-tenant asynchronous processing in Tomcat
About UI thread processing in Android asynchronous
[Swift] Implement tap and long press processing!
Asynchronous processing with Spring Boot using @Async
How to implement asynchronous processing in Outsystems