【发布时间】:2020-09-04 21:45:12
【问题描述】:
我正在修改swift 中的并发,我怀疑REPL 实际上并没有像在实时应用程序中那样运行DispatchQueue。我已经复制并粘贴了几个问题的代码,包括这个Swift: Simple DispatchQueue does not run & notify correctly:
let group = DispatchGroup()
let queue = DispatchQueue.global(qos: .default)
for i in 1...4 {
queue.async(group: group) {
print("???? \(i)")
}
}
for i in 1...4 {
queue.async(group: group) {
print("❌ \(i)")
}
}
group.notify(queue: .main) {
print("jobs done by group")
}
现在,当将其粘贴到 repl 时,我看到了一些旧队列项目和一些新队列项目 - 但不是所有预期的新队列项目。
???? 2
???? 4
image
video
???? 3
group: DispatchGroup = {
baseOS_dispatch_object@0 = {
baseOS_object@0 = {
baseNSObject@0 = {
isa = OS_dispatch_group
}
}
}
}
queue: OS_dispatch_queue_global = {
baseOS_dispatch_queue@0 = {
baseOS_dispatch_object@0 = {
baseOS_object@0 = {
baseNSObject@0 = {
isa = OS_dispatch_queue_global
}
}
}
}
}
然后我输入一些随机的附加语句 .. 并查看其他排队任务完成:
96> let x = 3
❌ 1
x: Int = 3
97> let x = 4
video
x: Int = 4
98> x
❌ 2
$R1: Int = 4
似乎很明显没有个后台线程正在运行。有没有办法在repl 中获得真正的并发/线程操作?
更新我将代码更改为.userInteractive,这有点帮助,但没有解决根本问题。
let queue = DispatchQueue.global(qos: .default)
结果仍然只是断断续续地发生。添加Thread.sleep() 会导致其中断:
let group = DispatchGroup()
let dispatchQueue = DispatchQueue.global(qos: .userInteractive)
for i in 1...5 {
group.enter()
dispatchQueue.async {
Thread.sleep(forTimeInterval: 3)
print("???? \(i)")
group.leave()
}
}
for i in 1...6 {
group.enter()
dispatchQueue.async {
Thread.sleep(forTimeInterval: 2)
print("❌ \(i)")
group.leave()
}
}
group.notify(queue: DispatchQueue.main) {
print("jobs done by group")
}
我们只得到结果的一个子集,它们之间没有发生sleep。
❌ 1
❌ 3
❌ 2
❌ 2
❌ 4
???? 2
所以这里有其他事情发生/需要。
另一个更新我只是在最后添加了两行代码:
Thread.sleep(forTimeInterval: 20)
print("Dispatcher done")
然后我在iOS Simulator 中运行它,行为有些不同。
- 打印语句全部执行
-
Thread.sleep()是对dispatchQueue.async()的调用中的 noop - 但
Thread.sleep()确实在循环外生效并导致主线程挂起。这是意料之中的。
这是在ios Simulator运行时的输出
【问题讨论】:
标签: swift multithreading read-eval-print-loop