wxPythonでsleepすると応答なしになる件

2020-08-13

プログラミング言語Python(パイソン)に関する話です。

Python

wxPythonでsleepを使うと応答なし

先日、wxPythonでsleep()を使うというイレギュラーなプログラムを作ったときに、プログラムが応答なし(フリーズする)になるという現象に遭遇しました。

この問題と解決方法について記載します。

確認環境

  • Windows 10 Home(64bit)
  • Python 3.8.2(64bit)
  • wxPython 4.0.7.post2

一応Python 3.8の32bit版と、Python 3.7の64bit版も試しましたが同じ状況でした。

現象について

当方の環境では、

  • メイン処理の中のtime.sleep()を3回以上使用すると「応答なし」
  • 現象は発生したり、しなかったり
  • 1度発生すると以降は確実に発生
  • PCの再起動で発生しなくなることがある
  • 応答なしになると、以降の処理がまともに動作しない
  • sleep()の時間を変えても改善せず

ちなみに当方の場合、sleep()を使用する目的は「定期実行」というよりは「処理の遅延」「待機」が目的になります。

当初、現象が100%発生していたので「何か対策が必要なのだろうな」と考えているときに、再起動で現象が発生しなくなり「ん?とりあえず大丈夫そうか?」となってしまい、そのまま進めると数日後にまた応答なしになるという状況…

100%動かなければもっと早く解決できたのですが。

ちなみに試してたこと

いろいろ調べて「wx.Sleep()」というものを見つけました。

「wxのSleep関数だし、これで解決じゃん!」

と思って意気揚々と試してみましたが、全然ダメでした。wx.MilliSleep()もダメでした。wx.MicroSleep()はUNIX用なので試していません。

調べていると「定期実行したい」という質問に対する回答はいくつか見かけたのですが「処理を遅延させたい」「待機したい」という質問と回答はなかなか見つけられませんでした。

原因

そもそもの原因について以下のような記載がありました。

質問に挙げたコードのように記述しますと、途中のループ処理が抜けるまで application.MainLoop() が呼ばれませんので、アプリケーションがまっとうに動作しません。

application.MainLoop() はイベントループなどとも呼ばる「ユーザやシステムからのイベントを待ちうけて、イベントの振り分け処理をする関数」ですので、この関数が呼ばれない限り「アプリケーションが応答しません」となってしまいます。

初心者です。sleep文を入れたら、アプリが正常に作動しなくなりました。

「一時停止して待機」と「イベント駆動型GUIプログラミング」は一緒に使用できません。メインGUIスレッドが何かを待ってブロックされている限り、他のイベントは処理できず、プログラムはフリーズしているように見えます。オプションは、(実際には待機しないことで)「待機」する方法を変更するか、別のスレッドを使用することです。

ある時点でコードを一時停止する

要するに、イベントドリブンのGUIプログラムのメインループで基本的にsleep()は使用できない、メインループは待機させちゃダメということなのでしょう。

対処法・解決策

別スレッドを作成して、その中でSleep()することにしました。

(私がやりたかったことは)それで解決しました。

サンプルコード

大体、以下のような感じです。

参考サイト

以上。

後記

最後までお読みくださりありがとうございます。

こんなに更新したのに、現在はほぼ誰も見ていないゴミカスクズ無価値ブログです。

よければ(はてな)ブックマークや拡散をお願いいたします。

更新の原動力として励ましが欲しいのです…<(_ _)>

当ブログ内お薦め記事

記事はここまでです。