队列不遵循QoS优先级

时间:2017-01-16 18:31:08

标签: ios swift grand-central-dispatch dispatch-async

问题:在遵循此tutorial时,我为2个队列分配了不同的QoS。但是,当我运行代码时,队列就像它们具有相同的优先级一样。此外,即使首先调用红点,蓝点也在红点之前打印。我在教程提供的completed project上运行了代码。

注意:有一次,当我在模拟器上删除应用程序并重新运行应用程序时,我得到了一个非常接近教程的output。但在再次运行代码后,我得到了下面的输出。即使再次删除并重新运行应用程序,也只会给我相同的输出。

代码

override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        queuesWithQoS()
}

func queuesWithQoS() {
        let queue1 = DispatchQueue(label: "com.appcoda.queue1", qos: DispatchQoS.userInitiated)
        let queue2 = DispatchQueue(label: "com.appcoda.queue2", qos: DispatchQoS.utility)

    queue1.async {
        for i in 0..<10 {
            print("", i)
        }
    }

    queue2.async {
        for i in 100..<110 {
            print("", i)
        }
    }
}

我的输出:

enter image description here

教程的输出:

enter image description here

2 个答案:

答案 0 :(得分:2)

这是一个构造相当糟糕的教程。我建议像这样重写:

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    queuesWithQoS()
}
let queue1 = DispatchQueue(label: "com.appcoda.queue1", qos: .userInitiated)
let queue2 = DispatchQueue(label: "com.appcoda.queue2", qos: .utility)
func queuesWithQoS() {
    queue1.async {
        for i in 0..<10 {
            NSLog("%@ %d", "", i)
        }
    }
    queue2.async {
        for i in 100..<110 {
            NSLog("%@ %d", "", i)
        }
    }
}

我做了两处修改:

  • 我已经给了队列持久性,将它们作为实例属性而不是本地实现;

  • 并且我使用NSLog代替print,因为print众所周知不是线程安全的,因此您正在尝试学习的内容就是您不会准确学习。

当我建立并运行时,我反复得到这样的东西:

2017-01-16 10:41:25.577 qosTest[3033:285702]  0
2017-01-16 10:41:25.577 qosTest[3033:285703]  100
2017-01-16 10:41:25.579 qosTest[3033:285702]  1
2017-01-16 10:41:25.579 qosTest[3033:285702]  2
2017-01-16 10:41:25.580 qosTest[3033:285702]  3
2017-01-16 10:41:25.579 qosTest[3033:285703]  101
2017-01-16 10:41:25.580 qosTest[3033:285702]  4
2017-01-16 10:41:25.580 qosTest[3033:285702]  5
2017-01-16 10:41:25.580 qosTest[3033:285703]  102
2017-01-16 10:41:25.581 qosTest[3033:285702]  6
2017-01-16 10:41:25.581 qosTest[3033:285702]  7
2017-01-16 10:41:25.581 qosTest[3033:285703]  103
2017-01-16 10:41:25.581 qosTest[3033:285702]  8
2017-01-16 10:41:25.582 qosTest[3033:285702]  9
2017-01-16 10:41:25.585 qosTest[3033:285703]  104
2017-01-16 10:41:25.586 qosTest[3033:285703]  105
2017-01-16 10:41:25.610 qosTest[3033:285703]  106
2017-01-16 10:41:25.611 qosTest[3033:285703]  107
2017-01-16 10:41:25.613 qosTest[3033:285703]  108
2017-01-16 10:41:25.615 qosTest[3033:285703]  109

这看起来更加现实:我们更喜欢一个线程而不是另一个线程,但我们不会在另一个线程上运行一个线程 。我建议教程的结果(可能是你的结果)只是一个粗心的编码。

答案 1 :(得分:0)

QoS不会直接为任务分配CPU优先级。通过分配QoS工作,您指示其重要性,但系统自行优先级

我得到的结果与您相同,但是如果我将QoS类从utility更改为background,则首先处理优先级较高的项,然后处理后台任务。以下是我修改后的示例(蓝色优先级为userInitiated,红色优先级为background

import PlaygroundSupport
import Dispatch

PlaygroundPage.current.needsIndefiniteExecution = true


let queue1 = DispatchQueue(label: "queue1", qos: .background, attributes: .concurrent)

let queue2 = DispatchQueue(label: "queue2", qos: .userInitiated, attributes: .concurrent)

queue1.async {
    for i in 0..<10 {
        print("", i)
    }
}

queue2.async {
    for i in 100..<110 {
        print("", i)
    }
}

enter image description here