Open1

DispatchQueue.globalに詰んだキューの同時実行限度があるのかを調べたい話

yimajoyimajo

はじめに

DispatchQueue.globalを使って取り出せて実行できるグローバルキューには総数があるんじゃないかと思い始めた。なぜならスレッドは無限じゃないし、スレッドを効率よく安全に使うためのDispatchQueueで同時に実行できる処理が無限とは思えないから。

何が言いたいか

DispatchQueue.global経由で作られたスレッドをスリープさせるコードをたまにみるんだけど、それをやるとOSがアプリに割り振ってくれたスレッドが止まり、DispatchQueue.globalがあらたに積まれたキューから実行をしてくれない。処理を待っているんじゃないかと思っている。という話。ツッコミどころなどあればコメントしていただきたいところ。

検証環境

  • Xcode 12.5
  • Playground

実験

DispatchQueue.globalをループで10秒待ってみる

キュー100個つくって同時に開始させ終了を10秒遅らせてみた。

結果はDispatchQueue.globalで同時に取り出せる64個があり、それで利用するキュー上でスレッド止められると64個以上のキューの処理はすぐには開始されず、時間が10秒たって終了した後、すでに積まれている処理が実行された。

コードは

import Foundation

for i in 1 ..< 100 {
    DispatchQueue.global(qos: .userInteractive).async {
        print(i, "start", Date())
        Thread.sleep(until: Date() + 10)
        print(i, "stop", Date())

    }
}

DispatchQueue.globalの実行優先度を調整してみる

奇数だったら優先度を低く、そうでなければ優先度を高くしてみる。

奇数の実行が比較的遅いのがわかる。

コードは

import Foundation

for i in 1 ..< 100 {
    let qos = ((i % 2) == 1) ? DispatchQoS.QoSClass.background : .userInteractive
    DispatchQueue.global(qos: qos).async {
        print(i, "⚡️start", Date())
        Thread.sleep(until: Date() + 10)
        print(i, "✋stop", Date())
    }
}