0

tkinter ウィジェットのインスタンスのみを持ち、tkinter のサブクラスではない GUI クラスがあります。この GUI クラスにはデータ処理オブジェクトのインスタンスもあり、実行に時間がかかるメンバー関数を呼び出します。GUI がフリーズするのを防ぎ、プログレス バーを更新するために、マルチプロセッシングを使用します。

outqueue = mp.Queue()
objqueue = mp.Queue()
progqueue = mp.Queue()
try:
     process = mp.Process(target=self.vromad.extractPlayers_mp,args=[outqueue, objqueue, progqueue])
     process2 = mp.Process(target=self.vromad.extractPlayers)
     process2.daemon = True
     process.daemon = True
     process.start()
     process2.start()
     print("started process")
     self.frame.after(500, self.updateBar, progqueue)
     print("bar should have started")
except:
     self.exceptionPopUp(traceback.format_exc())
     xtractStatus = -1
print("already here") 

ここで、動作が本当に興味深いものになります。最初のプロセスと同じ 2 番目のプロセスを実行して、マルチプロセッシングによるブロッキングが発生しているかどうかを確認します。いいえ、「開始されたプロセス」は、いずれかのタスクが終了する前に印刷されます。実際、process2.start() を追加すると、CPU 使用率が正確に 2 倍になります。さらに、バーが実際に更新される前に、「バーは開始されているはずです」と「すでにここにあります」が出力されます。実際、コールバック self.updateBar は、「すでにここに」AFTER 出力を出力します。

コードが実行され続けている間、すべての GUI イベントはすべてがアイドル状態になるまで延期されるように見えます。プロセスが完了するまでバーが更新されないだけでなく、ウィンドウ全体がフリーズするため、これは実際に当てはまるようです。self.frame.after の遅延時間を 10ms から 1000ms まで試しましたが、動作に変化はありませんでした。これは、tkinter がイベント ループを通過するのをブロックする tkinter の何らかの属性をプロセスが何らかの方法で取得したためですか? スレッド化に切り替えると、ここで役立ちますか?

4

1 に答える 1