❌ マルチスレッドにしても実際には単一のスレッドしか実行されない
❌ IOバウンド時はこのGILが解放されるということを知った
前提でされている状況の説明が何かおかしいです。
(意図は汲み取れますが、説明が誤解を招きそうな表現。多分、ニュアンスの問題)
IOバウンドな処理では、通常は、そもそもGILが問題になる事はありません。
GILの心配自体が杞憂です。
前提として、恐らく共有できていそうな認識では
非同期処理 | I/O bound | CPU bound |
---|
Multithread | o | x (GIL) |
Multiprocessing | o | o |
大筋の理解では、例えば、プログラムを組む際に
マルチスレッドかマルチプロセスかで悩んでいる、みたいな状況で
IOバウンド/CPUバウンドを判別の基準にする、は妥当な判断です。
Pythonのコードのみを対象とした場合は、大抵の場合正しいのですが、
マルチスレッドで GIL を回避 という選択肢もあります。
シリアル通信の読み取り待機時(pyserialのread()で待機している時)にもGILは解放されるのでしょうか。
GIL が掛かるのは、インタープリタでのバイトコードの実行単位でのロックなので、
Pythonのコードではなく、バイトコードやC拡張の内部のコード単位で論じる必要があります。
GILの理解が目的で質問されてる場合を想定して、細かい点ですが
IOバウンドな処理で、待機中であればPythonのコードを実行する必要はないので、
その間は GIL を解放する事ができます(ニュアンス的には、解放しても良い)。
しかし、これは実装次第であり、因果関係が、IOバウンドな処理だから解放されるという訳ではありません。
GIL を解放しない IO処理自体は成立します。(大抵、不具合扱いされますが)
pyserialのread()で待機している時
read() 内には複数の処理があります。
プラットフォーム毎にも実装が異なるので、実際にコードを書いて調べて見ましょう。
posix の場合、select/os.read を使った読み出し。実装は C 拡張。
https://github.com/python/cpython/blob/main/Python/fileutils.c
Release the GIL to call read(). The caller must hold the GIL.
例えば、windows の場合だと ctypes.WinDLL を経由し外部関数を呼び出してます。
WinDLL では、呼び出し前後で GIL が解放・獲得されます。
https://docs.python.org/ja/3/library/ctypes.html#ctypes.WinDLL
これらのライブラリがエクスポートするどの関数でも呼び出す前に Python GIL (global interpreter lock) は解放され、後でまた獲得されます。
こちらのケースでは、IOバウンドだから解放されるわけではなく、
外部関数呼び出しは、Pythonのオブジェクトを直接参照することが出来ないので、
一律でGILは解放してから呼び出すようになってます。
但し、read() 内にも複数の処理があり、Pythonのオブジェクトを扱う場面(バッファリングの部分等)では
依然として GIL を獲得しています。→ read()内部の実装詳細単位でみる必要がある。
結論ですが、read() 関数全体で見た場合、GILを獲得する部分もありますが、
CPU負荷では無い為、GILが問題(パフォーマンス上のボトルネック)となる事はありません。
参考
Python is NOT Single Threaded (and how to bypass the GIL)
- Python is a single threaded language ... no
- If you want to use multiple cores in python,
don't use threading and use multiprocessing instead ... no
単純に「正解」「間違い」という意図ではありませんが、
「誤解」されやすい話題として取り上げられてます。
「単一のスレッドしか実行されない」は、流石に言葉不足で、誤解を招く表現だと思います。
2つ目の項目については、マルチスレッドでも CPUバウンドな処理をする際に
GIL を回避する方法がある、という主旨です。
他にも、GIL対策としては、公式にサブインタープリター単位のロックを導入する取り組みもありますが、
まだあまり実用的な段階ではない印象。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。