GUI

Python Tkinter Event Loop(4) 非同期I/O

タイマーイベントは、長く続く計算を中断するためのもので、各ステップが迅速に完了することが保証されているため、ハンドラはイベントループに戻ることができる。

処理がすぐに終わらない場合を考える。OSに様々な呼び出しをした際に発生する可能性があり、最も一般的なのは、何らかのI/O(ファイルの書き込み、データベースとの通信、リモートウェブサーバーからのデータ取得など)を行う場合だ。

ほとんどのI/Oコールはブロッキングされ、操作が完了(または失敗)するまで返されない。代わりに使いたいのは、ノンブロッキングまたは非同期のI/Oコール。非同期I/O呼び出しを行うと、操作が完了する前にすぐに返される。コードはそのまま実行し続けることができ、この場合、イベントループに戻りる。その後、I/O操作が完了すると、プログラムが通知され、I/O操作の結果を処理することができる。

I/Oを別の種類のイベントとして扱っており、イベント駆動型I/Oとも呼ばれる。(Pythonでは、非同期I/Oはasyncioモジュールとその上のレイヤーの他のモジュールによって提供される。)

すべてのasyncioアプリケーションはイベントループに大きく依存している。Tkinterは素晴らしいイベントループを持っている。残念ながら、asyncioのイベントループとTkinterのイベントループは同じではない。少なくとも同じスレッド内で両方を同時に実行することはでない(一方が他方を繰り返し呼び出すことはできるが、壊れやすい)。

推奨されるのは、メインスレッドでTkinterを維持し、別のスレッドでasyncioイベントループをスピンオフすること。

メインスレッドで実行されているアプリケーションのコードは、他のスレッドで実行されているasyncioイベントループと連携する必要があるかもしれない。asyncio call_soon_threadsafe メソッドを使えば、asyncioイベントループのスレッドで動いている関数を(Tkinterイベントループからでも、例えばウィジェットコールバックで)呼び出すことができる。asyncioイベントループからTkinterを呼び出す方法は次の節で説明する。