I'm trying to figure out how sync and async methods work in GCD, but I made some test and don't really understand the result. This is a code from Playground
PlaygroundPage.current.needsIndefiniteExecution = true
let queueA = DispatchQueue(label: "my-awesome-queue")
let queueB = DispatchQueue(label: "one-more-awesome-queue", attributes: .concurrent)
for _ in 0...5 {
queueA.sync {
Thread.sleep(forTimeInterval: 0.2)
print("😁")
}
}
for _ in 0...5 {
queueB.async {
Thread.sleep(forTimeInterval: 0.2)
print("😡")
}
}
And result is
😁
😁
😁
😁
😁
😁
😡
😡
😡
😡
😡
😡
I don't really understand, why queueA blocks async tasks from other queue (queueB)? I thought different queues could be executed from different threads, and there are no problems to run sync queue and different async queue simultaneously. Or custom sync queues block any other queues (even main queue)?
Basically using sync
from the main thread is always wrong, because now you are blocking the main thread. And that is exactly what you are doing! Only a background thread should sync
onto another thread.
and there are no problems to run sync queue and different async queue simultaneously
Yes, there are. Nothing can happen "simultaneously". Everything has to "take turns".
Or custom sync queues block any other queues (even main queue)?
Yes. While Queue A is being called with sync
and is sleeping, the calling thread (which in your code is the main thread) is blocked. You are not allowing things to "take turns". We cannot proceed to the Queue B calls because we are stuck in the Queue A calls.
You will also notice that the Queue B results arrive much faster than the Queue A results did. That is because Queue B is being called with async
and is concurrent, so the whole second loop, when it runs, runs immediately, doing all the loops, and so all the results arrive together. This is even more obvious if you print Date().timeIntervalSince1970
together with your output.