我需要帮助以更好地了解Swift中的并发工作方式。
我有代码:
DispatchQueue.main.async {
DispatchQueue.main.async {
print("A")
DispatchQueue.main.async {
print("B")
}
print("C")
}
print("D")
}
结果: D A C B
我猜“ D”仅是第一个原因,执行第一个Dispatch块包括2个步骤:
比执行 print(“ D”)需要更多的时间。是吗?
当我尝试并发队列时,在一种情况下,我得到了下一个结果: A D C B 。
为什么会这样?
并发队列代码:
DispatchQueue.global(qos: .utility).async {
DispatchQueue.global(qos: .utility).async {
print("A")
DispatchQueue.global(qos: .utility).async {
print("B")
}
print("C")
}
print("D")
}
答案 0 :(得分:1)
此行为的原因是,可能有许多具有相同QoS的全局队列,但始终只有一个主队列。
您的第一个示例是可预测的-它的行为始终相同,因为您始终将任务分派到同一队列-main。用async
提交的任务将异步执行(这意味着async
函数将立即返回),但是新任务直到当前执行的任务完成后才开始执行。这是发生的事情的简化模型:
Task 1:
Submit task 2
Print "D"
Task 2:
Print "A"
Submit task 3
Print "C"
Task 3:
Print "B"
Task 1
包括提交Task 2
和打印内容。 Task 1
正在主队列上运行,并且Task 2
已添加到同一队列。这意味着Task 2
在当前运行的任务-Task 1
-完成执行之前无法启动。
Seconf示例有点不同。每次调用DispatchQueue.global
时,都可以确保获得具有特定QoS的队列,但不一定是同一队列。您派遣print("A")
的队列似乎没有任何其他待处理任务,并且能够在返回async
方法之前立即执行其工作。
使用先前提供的模型-如果将Task 2
添加到与正在运行的Task 1
不同的队列中,则无需等待Task 1
完成执行。但是同样,在这种情况下,这完全取决于每次调用DispatchQueue.global
时获得的队列,并且不能保证