我试图在主队列上运行多个任务,其中一些比其他任务更紧急。我使用DispatchQoS执行此操作:
func enqueue(_ prio: Int) {
let qos = DispatchQoS(qosClass: .userInteractive, relativePriority: prio)
DispatchQueue.main.async(qos: qos) {
NSLog("\(prio)")
}
}
for i in 1...5 {
for prio in -15...0 {
enqueue(prio)
}
}
我希望看到五个零,然后是五个-1,然后是五个-2,依此类推。
但我得到了:
-15 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 -15 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 -15 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 -15 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 -15 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0
换句话说,调度队列按照他们排队的顺序执行任务,忽略优先级。
然后我尝试了不同的QoS类而不是不同的relativePriority:
func enqueue(_ qos: DispatchQoS) {
DispatchQueue.main.async(qos: qos) {
NSLog("\(qos.qosClass)")
}
}
for i in 1...10 {
enqueue(.background)
enqueue(.utility)
enqueue(.userInitiated)
enqueue(.userInteractive)
}
但是这些任务再次按入队顺序执行,忽略了QoS。
如何让调度队列尊重QoS?我的目标是在主队列上运行一些优先级低于其他任务的任务。
答案 0 :(得分:2)
在WWDC 2016视频Concurrent Programming with GCD in Swift 3中,他们提到当您向具有更高优先级的队列添加内容时,它不会“跳过队列”,而是使用QoS来解析优先级倒置(例如可以使用它来增加队列中先前任务的优先级,以满足高QoS后续任务,而不是改变串行队列中任务的顺序。)
另外,我建议你不要用主队列测试这种东西。这是一个带有专用线程的特殊串行队列,因此对于检查QoS如何影响任务的调度和优先级并不是非常有用。我建议创建自己的并发队列来测试QoS问题。此外,如果您向并发队列添加任务,它们通常必须足够实用且足够多,以查看任何可辨别的模式。
最后,我建议您观看WWDC 2015视频Building Responsive and Efficient Apps with GCD,因为它会更详细地介绍QoS。上述2016年视频适用于Swift 3特定观测,但它确实建立在2015年视频的QoS讨论基础之上。
答案 1 :(得分:1)
解决方案原来是使用OperationQueue:
cout << setw(10) << i
<< setw(10) << std::to_string(i) + ch;
然后我可以一个接一个地继续执行低优先级任务,而不会使UI无响应。
感谢Rob指出为什么DispatchQueues不尊重优先事项。