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 總是按順序呼叫(*在操場上)。
不知道為什么上面和下面的代碼執行結果不一樣。
是否有多個全域佇列?
uj5u.com熱心網友回復:
我運行了你的代碼并得到:
B
B
A
D
A
C
C
D
因此,所有 8 個列印陳述句都相互交錯,并非完全隨機,也沒有特定的模式。較早的列印陳述句往往比較晚的列印陳述句執行得早一點,但基本上它是不可預測的——它是異步的。
uj5u.com熱心網友回復:
它們以正確的順序列印可能只是一個巧合。DispatchQueue.global()說的檔案。
提交到回傳佇列的任務是相互并發調度的。 https://developer.apple.com/documentation/dispatch/dispatchqueue/2300077-global#
因為它說它們是同時安排的(而不是串行),所以不應該期望它們總是以相同的順序列印。
異步任務也沒有真正做任何事情。我懷疑它們之間沒有足夠的可變性來導致列印不同的順序。
DispatchQueue.global()看起來它總是根據我在操場上看到的記憶體地址回傳相同的實體。它可能在幕后做一些額外的事情,這可能會給每個異步任務的執行時間帶來一點變化。
交換代碼中兩個測驗的順序也為我產生了不同的輸出,確認不應依賴該順序。
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")
}
uj5u.com熱心網友回復:
let a = DispatchQueue.global()
DispatchQueue.global().async {
print("A")
}
DispatchQueue.global().async {
print("B")
}
DispatchQueue.global().async {
print("C")
}
DispatchQueue.global().async {
print("D")
}
a.async {
print("1")
}
a.async {
print("2")
}
a.async {
print("3")
}
a.async {
print("4")
}
A
1 // usually first or second
C
D
B
2
3
4
我嘗試了多種配置,但最讓我印象深刻的是這一配置。如果在向任何佇列提交任何內容之前在屬性中捕獲佇列,則捕獲佇列中的第一個任務幾乎總是在所有任務中首先或第二個執行。我還觀察到行內佇列中的任務幾乎總是隨機執行,而其他任務幾乎總是串行執行。將所有這些放在一起,似乎在屬性中捕獲全域佇列使該佇列的優先級略高于行內訪問的佇列。所有這些測驗都是在操場上完成的,所以這些在生產環境中可能沒有任何意義。
uj5u.com熱心網友回復:
其他答案已經討論了執行塊的順序,但我想直接解決您的問題:“是否DispatchQueue.global().async創建一個新的全域佇列?”
它不是。
我們可以通過列印ObjectIdentifier佇列的經驗來檢查:
import Dispatch
let q = DispatchQueue.global()
print(ObjectIdentifier(DispatchQueue.global()))
print(ObjectIdentifier(q))
它列印ObjectIdentifier兩次相同的內容,因此兩次呼叫都DispatchQueue.global()回傳相同的物件。
我們也可以通過查看源代碼來回答這個問題。DispatchQueue.global()是 C 函式的 Swift 包裝器dispatch_get_global_queue。來源在這里:
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. 來源在這里:
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];
}
這只是一個陣列查找,所以每次都回傳相同的值,除非內容發生_dispatch_root_queues變化——但它沒有發生變化。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/384663.html
