In Swift, Grand Central Dispatch API (GCD) sopports thread programming.
Just using GCD is not difficult, but there are many preceding concepts to understand.
After understanding concepts, I arrange three types of gcd queues, and queues examples accordingly.
Preceding concepts
Synchronous vs. Asynchronous
When the new thread is forked from original threa, we do the task parrallely.
Synchoronous origin thread wait until ending new thread. After new thread exit tasks, then origin thread get the return value of that thread, and continue the tasks.
Asynchoronous origin thread do not wait until the end of new thread. Therefore, Asynchoronous origin thread immediately get return value from new thread, and continue task.
Serial vs Concurrent Queue
iOS supports either serial queue and concurrent queue GCD.
ref : https://www.raywenderlich.com/5370-grand-central-dispatch-tutorial-for-swift-4-part-1-2
Serial queue is FIFO(First In, First Out), which usually called as queue in data structure concepts.
But then, what is concurrent queue?
ref : https://www.raywenderlich.com/5370-grand-central-dispatch-tutorial-for-swift-4-part-1-2
Before knowing concurrent queue, we need to know βconcurrentβ first.
It is easy to mistake that Concurrent is Parallelism.
When we do multi- threading, we can see threads are running parallely.
ref : https://www.raywenderlich.com/5370-grand-central-dispatch-tutorial-for-swift-4-part-1-2
System memory resource is limitied and should be occupied by a thread, OS needs to switch thread which occupying OS memory resource continously. we call this situation as Concurrency.
Therefore, Relationship between parallelism and concurrency is like below.
Parallelism requires concurrency, but concurrency does not guarantee parallelism.
These are all concepts which included in GCD.
Three types of gcd queues
Main queue
Main queue is queue running on the main thread of iOS, ans is serial queue.
Global queues
Global queues are running on the many thread in whole iOS, and they are all concurrent queues.
Especially, Global queue supports specific properties which is called Quality of Service (QoS). QoS has 4 properties which decides priority on concurrent global queue.
QoS
User - Interactive It is for UI task, and event handling which is short and must complete. Running on main thread, even global queue.
User-initiated It is for user request which requires immediate result whith ensuring non-block UI.
Utility Treat the task which takes long time. It usually used for calculating, networking, I/O.
Background The task which do not need for UI, and not that important as well.
and if you do not add any properties on glabal queue, this automatically set βDefaultβ QoS property.
This example shows how to insert qos property on global queue.
// 1
DispatchQueue.global(qos: .userInitiated).async { [weak self] in
guard let self = self else {
return
}
let overlayImage = self.faceOverlayImageFrom(self.image)
// 2
DispatchQueue.main.async { [weak self] in
// 3
self?.fadeInNewImage(overlayImage)
}
}
ref : https://www.raywenderlich.com/5370-grand-central-dispatch-tutorial-for-swift-4-part-1-2
Coustom queues
Custom queues are created by user, it can be either serial and concurrent.
Examples
Of course we read about the concepts about queues, but code examples can make us understand more easiler.
- Sync vs Async
- Serial vs Concurrent
Global Sync
this blog gave me insight to express example with fruit emoji.
- https://zeddios.tistory.com/516
Global Sync prints pear, and the other just prints apple.
DispatchQueue.global().sync {
print("global start!=============")
for i in 1...5 {
print("π"+" \(i)ea")
}
print("global end! =============")
}
for i in 1...5 {
print("π"+" \(i)ea")
}
Because Global queue synchronously excuted, the next task will be procceed after global queue task.
global start!=============
π 1ea
π 2ea
π 3ea
π 4ea
π 5ea
global end! =============
π 1ea
π 2ea
π 3ea
π 4ea
π 5ea
Global Async
Global Async prints pear, and the other just prints apple.
DispatchQueue.global().async {
print("global start!=============")
for i in 1...5 {
print("π"+" \(i)ea")
}
print("global end! =============")
}
for i in 1...5 {
print("π"+" \(i)ea")
}
Because Global queue asynchronously excuted, the next task excuted parallely.
// 1 trial
global start!=============
π 1ea
π 1ea
π 2ea
π 3ea
π 2ea
π 4ea
π 5ea
π 3ea
π 4ea
π 5ea
global end! =============
// 2 trial
global start!=============
π 1ea
π 1ea
π 2ea
π 2ea
π 3ea
π 3ea
π 4ea
π 5ea
π 4ea
π 5ea
global end! =============
Custom Serial Sync
Global Sync prints pear and peach, and the other just prints apple.
let WDFruits = DispatchQueue(label: "WD")
WDFruits.sync {
print("custom start!=============")
for i in 1...5 {
print("π"+" \(i)ea")
}
print("custom end!=============")
}
WDFruits.sync {
print("custom start!=============")
for i in 1...5 {
print("π"+" \(i)ea")
}
print("custom end!=============")
}
for i in 1...5 {
print("π"+" \(i)ea")
}
This example confused for me at first.
In summary,
Serial makes custom queue run first before running main task.
sync makes running peach first, rather than pear.
custom start!=============
π 1ea
π 2ea
π 3ea
π 4ea
π 5ea
custom end!=============
custom start!=============
π 1ea
π 2ea
π 3ea
π 4ea
π 5ea
custom end!=============
π 1ea
π 2ea
π 3ea
π 4ea
π 5ea
Custom Serial Async
Global Async prints pear and peach, and the other just prints apple.
let WDFruits = DispatchQueue(label: "WD")
WDFruits.async {
print("custom start!=============")
for i in 1...5 {
print("π"+" \(i)ea")
}
print("custom end!=============")
}
WDFruits.async {
print("custom start!=============")
for i in 1...5 {
print("π"+" \(i)ea")
}
print("custom end!=============")
}
for i in 1...5 {
print("π"+" \(i)ea")
}
Async makes do custom task parallely, and Serial makes serperate between custom queue and main task.
custom start!=============
π 1ea
π 1ea
π 2ea
π 2ea
π 3ea
π 3ea
π 4ea
π 5ea
π 4ea
π 5ea
custom end!=============
custom start!=============
π 1ea
π 2ea
π 3ea
π 4ea
π 5ea
custom end!=============
Conclusion
This is summary about GCD API. Futhermore, there are many other functions and properties in GCD. I will post more about it later.
I hope this summary and examples helps you:)