DispatchQueue.global().async {
print("A")
}
DispatchQueue.global().async {
print("B")
}
DispatchQueue.global().async {
print("C")
}
DispatchQueue.global().async {
print("D")
}
let a = DispatchQueue.global()
a.async {
print("A")
}
a.async {
print("B")
}
a.async {
print("C")
}
a.async {
print("D")
}
If the global queue is not stored in a variable, the order of A, B, C, D is different each time.
When the global queue is stored in a variable, A, B, C, and D are called in sequence always(*in a playground).
I wonder why the code execution results above and below are different.
Are there multiple global queues?
Other answers have discussed the order in which blocks are executed, but I want to directly address your question: “Does DispatchQueue.global().async
make a new global queue?”
It does not.
We can check empirically by printing the ObjectIdentifier
of the queue:
import Dispatch
let q = DispatchQueue.global()
print(ObjectIdentifier(DispatchQueue.global()))
print(ObjectIdentifier(q))
It prints the same ObjectIdentifier
twice, so both calls to DispatchQueue.global()
return the same object.
We can also answer the question by looking at the source code. DispatchQueue.global()
is a Swift wrapper for the C function dispatch_get_global_queue
. The source is here:
dispatch_queue_global_t
dispatch_get_global_queue(intptr_t priority, uintptr_t flags)
{
dispatch_assert(countof(_dispatch_root_queues) ==
DISPATCH_ROOT_QUEUE_COUNT);
if (flags & ~(unsigned long)DISPATCH_QUEUE_OVERCOMMIT) {
return DISPATCH_BAD_INPUT;
}
dispatch_qos_t qos = _dispatch_qos_from_queue_priority(priority);
#if !HAVE_PTHREAD_WORKQUEUE_QOS
if (qos == QOS_CLASS_MAINTENANCE) {
qos = DISPATCH_QOS_BACKGROUND;
} else if (qos == QOS_CLASS_USER_INTERACTIVE) {
qos = DISPATCH_QOS_USER_INITIATED;
}
#endif
if (qos == DISPATCH_QOS_UNSPECIFIED) {
return DISPATCH_BAD_INPUT;
}
return _dispatch_get_root_queue(qos, flags & DISPATCH_QUEUE_OVERCOMMIT);
}
It calls _dispatch_get_root_queue
. The source for that is here:
DISPATCH_ALWAYS_INLINE DISPATCH_CONST
static inline dispatch_queue_global_t
_dispatch_get_root_queue(dispatch_qos_t qos, bool overcommit)
{
if (unlikely(qos < DISPATCH_QOS_MIN || qos > DISPATCH_QOS_MAX)) {
DISPATCH_CLIENT_CRASH(qos, "Corrupted priority");
}
return &_dispatch_root_queues[2 * (qos - 1) + overcommit];
}
It's just an array lookup, so it returns the same value every time, unless the contents of _dispatch_root_queues
changes—which it doesn't.