gpt4 book ai didi

ios - 异步操作并发理解

转载 作者:可可西里 更新时间:2023-11-01 01:58:23 26 4
gpt4 key购买 nike

这些队列管理您提供给 GCD 的任务并以 FIFO 顺序执行这些任务。这保证了添加到队列中的第一个任务是队列中第一个启动的任务,添加的第二个任务将是第二个启动的任务,依此类推。下面的代码

let anotherQueue = DispatchQueue(label: "com.gcdTest.Queue", qos: .userInteractive)
anotherQueue.async {
anotherQueue.async{
anotherQueue.async{
anotherQueue.async {
print("task 6")
for _ in 1...300 { }
}
}
print("task 3")
for _ in 301...600 {}
}
anotherQueue.async{
anotherQueue.async{
print("task 5")
for _ in 700...900 {}
}
print("task 4")
for _ in 5000...7000 {}
}
print("task 1")
for _ in 9000...10000 {}
}
anotherQueue.async {
print("task 2")
for _ in 1...1000 {}
}

产生输出

task 1
task 2
task 3
task 4
task 5
task 6

但是当我们在 Concurrent 中运行相同的代码时,它会产生不可预测的输出。例如:- 将第一行代码更改为下面的行

let anotherQueue = DispatchQueue(label: "com.gcdTest.Queue", qos: .userInteractive, attributes: .concurrent)

输出

task 3
task 2
task 1
task 4
task 5
task 6

根据定义,它指出并发队列中的任务保证按照它们被添加的顺序开始……这就是你得到的全部保证!

因此,期望串行队列(默认情况下)产生类似的输出。 (任务 1、任务 2、任务 3、任务 4、任务 5、任务 6)请任何人帮助我,我哪里出错了。

最佳答案

最重要的是,GCD 将始终按照任务被分派(dispatch)到该队列的顺序启动队列中的任务。在串行队列的情况下,这意味着它们将按顺序运行,并且这种行为很容易观察到。

然而,在并发队列的情况下,虽然它会按排队顺序启动任务,但对于连续快速分派(dispatch)的任务,它们也可能全部连续快速启动,彼此并发运行。简而言之,它们可能几乎同时开始运行,因此您无法保证哪个会先遇到各自的 print 语句。仅仅因为并发队列在几毫秒后开始一个任务,这并不能保证这两个任务遇到它们各自的 print 语句的顺序。

简而言之,print 语句序列不是确定性行为,而是具有不确定性行为的简单竞赛。


顺便说一句,虽然很明显您的示例在并发队列上使用时引入了竞争,但应该注意的是,由于您的嵌套分派(dispatch)语句,您的串行队列也会有竞争条件。看起来行为顺序在串行队列上是完全可以预测的,但事实并非如此。

让我们考虑一下您示例的简化版本。我假设我们将从主线程开始:

queue.async {
queue.async {
print("task 3")
}
print("task 1")
}
queue.async {
print("task 2")
}

显然,任务 1 将首先添加到队列中,如果该队列空闲,它将立即在该后台线程上启动,同时主线程继续执行。但是当主线程上的代码接近任务 2 的调度时,任务 1 将开始并继续调度任务 3。在调度任务 2 和任务 3 之间有一场经典的竞赛。

现在,实际上,您会看到任务 2 在任务 3 之前分派(dispatch),但引入非确定性行为并不需要太多延迟。例如,在我的计算机上,如果在调度任务 2 之前,Thread.sleep(forTimeInterval: 0.00005) 表现出非确定性行为。但即使没有延迟(或 for 循环一定次数的迭代),行为在技术上也是不确定的。


但是我们可以创建一个简单的示例来消除上述示例中隐含的竞争,但仍然可以说明您最初询问的串行和并发队列行为之间的区别:

for i in 0 ..< 10 {
queue.async { [i] in
print(i)
}
}

这保证在串行队列上按顺序打印,但在并发队列上不一定如此。

关于ios - 异步操作并发理解,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49145005/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com