简体   繁体   中英

Queues not following QoS priority

Problem: When following this tutorial , I assigned different QoS to the 2 queues. However, when I ran the code, the queues act as if they have the same priority. Further, the blue dots are printing before the red dots even though the red dots are called first. I ran the code on the completed project provided by the tutorial.

Note: Once, when I deleted the app on the simulator and re-ran the app, I got an output that was very close to the tutorial's. But after running the code again, I got the output below. Even deleting and re-running the app again, just gives me the same output.

Code

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)
        }
    }
}

My Output:

在此处输入图片说明

Tutorial's output:

在此处输入图片说明

That's a rather badly constructed tutorial. I would suggest rewriting like this:

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)
        }
    }
}

I've made two changes:

  • I've given the queues persistence, embodying them as instance properties rather than locals;

  • and I've used NSLog instead of print , because print is notoriously not thread-safe so that exactly the thing you are trying to learn is just what you won't accurately learn.

When I build-and-run, I repeatedly get something like this:

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

That seems much more realistic: we prefer one thread over another but we do not run one thread exclusively over the other. I would suggest that the tutorial's result (and probably your result) is just a figment of careless coding.

QoS does not directly assign CPU priority to tasks. By assigning a QoS to work, you indicate its importance , but the system prioritizes it on its own.

I am getting the same results as you, but if I change the QoS class from utility to background , the higher priority item is processed first and the background task later. Here is my modified example (blue is higher priority - userInitiated , red is background now.

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)
    }
}

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM