`DispatchQueue.global().async` 是否创建新的全局队列?
Does `DispatchQueue.global().async` make new global queue?
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")
}
如果全局队列没有存储在变量中,每次A、B、C、D的顺序都不一样。
当全局队列存储在变量中时,总是按顺序调用 A、B、C 和 D(*在操场上)。
我想知道为什么上面和下面的代码执行结果不同。
是否有多个全局队列?
我运行你的代码并得到:
B
B
A
D
A
C
C
D
所以所有 8 个打印语句都相互交错,不完全是 运行domly,但也没有特定的模式。较早的打印语句往往会比较晚的打印语句早一点执行,但基本上它是不可预测的——它是异步的。
他们以正确的顺序打印可能只是巧合。 DispatchQueue.global()
的文档说。
Tasks submitted to the returned queue are scheduled concurrently with respect to one another.
https://developer.apple.com/documentation/dispatch/dispatchqueue/2300077-global#
因为它说它们是同时安排的(而不是连续安排的),所以不应期望它们总是以相同的顺序打印。
异步任务也没有真正做任何事情。我怀疑它们之间没有足够的可变性来导致打印不同的订单。
根据我在操场上看到的内存地址,DispatchQueue.global()
看起来总是 returns 相同的实例。它可能在幕后做了一些额外的事情,可能会在每个异步任务的执行时间中引入一点可变性。
交换代码中两个测试的顺序也为我产生了不同的输出,确认不应依赖该顺序。
A2
C2
D2
B2
A1
B1
C1
D1
let a = DispatchQueue.global()
a.async {
print("A2")
}
a.async {
print("B2")
}
a.async {
print("C2")
}
a.async {
print("D2")
}
DispatchQueue.global().async {
print("A1")
}
DispatchQueue.global().async {
print("B1")
}
DispatchQueue.global().async {
print("C1")
}
DispatchQueue.global().async {
print("D1")
}
其他答案已经讨论了块的执行顺序,但我想直接回答你的问题:“DispatchQueue.global().async
是否创建一个新的全局队列?”
没有。
我们可以通过打印队列的 ObjectIdentifier
来凭经验检查:
import Dispatch
let q = DispatchQueue.global()
print(ObjectIdentifier(DispatchQueue.global()))
print(ObjectIdentifier(q))
它打印相同的 ObjectIdentifier
两次,因此两次调用 DispatchQueue.global()
return 相同的对象。
我们也可以通过查看源代码来回答问题。 DispatchQueue.global()
是 C 函数 dispatch_get_global_queue
的 Swift 包装器。来源是 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);
}
它调用 _dispatch_get_root_queue
。来源是 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];
}
这只是一个数组查找,所以它 return 每次都是相同的值,除非 _dispatch_root_queues
的内容发生变化——但事实并非如此。
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")
}
如果全局队列没有存储在变量中,每次A、B、C、D的顺序都不一样。
当全局队列存储在变量中时,总是按顺序调用 A、B、C 和 D(*在操场上)。
我想知道为什么上面和下面的代码执行结果不同。
是否有多个全局队列?
我运行你的代码并得到:
B
B
A
D
A
C
C
D
所以所有 8 个打印语句都相互交错,不完全是 运行domly,但也没有特定的模式。较早的打印语句往往会比较晚的打印语句早一点执行,但基本上它是不可预测的——它是异步的。
他们以正确的顺序打印可能只是巧合。 DispatchQueue.global()
的文档说。
Tasks submitted to the returned queue are scheduled concurrently with respect to one another. https://developer.apple.com/documentation/dispatch/dispatchqueue/2300077-global#
因为它说它们是同时安排的(而不是连续安排的),所以不应期望它们总是以相同的顺序打印。
异步任务也没有真正做任何事情。我怀疑它们之间没有足够的可变性来导致打印不同的订单。
根据我在操场上看到的内存地址,DispatchQueue.global()
看起来总是 returns 相同的实例。它可能在幕后做了一些额外的事情,可能会在每个异步任务的执行时间中引入一点可变性。
交换代码中两个测试的顺序也为我产生了不同的输出,确认不应依赖该顺序。
A2
C2
D2
B2
A1
B1
C1
D1
let a = DispatchQueue.global()
a.async {
print("A2")
}
a.async {
print("B2")
}
a.async {
print("C2")
}
a.async {
print("D2")
}
DispatchQueue.global().async {
print("A1")
}
DispatchQueue.global().async {
print("B1")
}
DispatchQueue.global().async {
print("C1")
}
DispatchQueue.global().async {
print("D1")
}
其他答案已经讨论了块的执行顺序,但我想直接回答你的问题:“DispatchQueue.global().async
是否创建一个新的全局队列?”
没有。
我们可以通过打印队列的 ObjectIdentifier
来凭经验检查:
import Dispatch
let q = DispatchQueue.global()
print(ObjectIdentifier(DispatchQueue.global()))
print(ObjectIdentifier(q))
它打印相同的 ObjectIdentifier
两次,因此两次调用 DispatchQueue.global()
return 相同的对象。
我们也可以通过查看源代码来回答问题。 DispatchQueue.global()
是 C 函数 dispatch_get_global_queue
的 Swift 包装器。来源是 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);
}
它调用 _dispatch_get_root_queue
。来源是 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];
}
这只是一个数组查找,所以它 return 每次都是相同的值,除非 _dispatch_root_queues
的内容发生变化——但事实并非如此。