7

私はリアルタイムのデータ処理と表示を行っており、60 秒ごとにデータベースにアクセスしています。time.sleep()60秒ごとに待機するために使用したくありません。これは、制御を削除し(つまり、変数へのREPLアクセスであり、必要ではありませんが便利です)、matplotlibチャートをフリーズするためです。

代替手段はありますか?理想的には、最初にユーザーにコントロールを与え、60 秒後にコントロールを奪い、コードを実行し、プロットを更新してから、ユーザーにコントロールを戻します。(私がコントロールと言うとき、私は REPL コントロールを意味します)。

何か案は?

4

1 に答える 1

12

ユーザー コントロールを取り除く必要がない場合、これを行うための非常に簡単な方法がありますthreading.Timer

あなたがしたいことは、関数の「継続」、つまり、の後に来るすべてのものを取り、time.sleepそれを別の function に移動し、次のmy_functionようにスケジュールすることです:

threading.Timer(60, my_function).start()

の最後に、まったく同じコード行でmy_function新しい をスケジュールします。Timer

Timerかなり扱いにくいインターフェースと実装ですが、stdlib に組み込まれています。たとえば、タイマーごとのスレッドではなく 1 つのスレッドで複数のタイマーを実行したり、定期的な呼び出しをスケジュールしたりできるため、自分でスケジュールを変更し続ける必要がなくなります。 60秒ごとに実行されるものについては、Timer.

注意すべき点: REPL でユーザーが処理しているのと同じデータをバックグラウンド ジョブで処理する必要がある場合、競合状態が発生する可能性があります。多くの場合、インタラクティブな環境 (特に Python では、GIL のおかげ) では、競合を引き起こさないようにユーザーに責任を負わせることができます。そうでない場合は、何らかの同期が必要になります。

留意すべきもう 1 つの点: GUI の作業を行おうとしている場合、使用している GUI によっては (matplotlib構成可能だと思いますが、デフォルトではtkinter?)、バックグラウンド スレッドから GUI を更新できない場合があります。

しかし、とにかくその場合には、実際にはより良い解決策があります。GUI プログラムには、何らかのスレッドで実行されるイベント ループがあり、これまでに設計されたほとんどすべてのイベント ループには、そのスレッドでタイマーをスケジュールする方法があります。の場合、オブジェクトtkinterへのハンドルがある場合は、代わりに をroot呼び出すだけで、不要なリソースを無駄にすることなく、GUI と同じスレッドで実行されます。root.after(60000, my_function)threading.Timer(60, my_function).start()

于 2013-03-01T21:43:26.320 に答える