0

TideSDK で GUI をフリーズせずに Python で長い処理ループを実行する方法はありますか? または、スレッドを使用する必要があります...

ありがとう。

4

1 に答える 1

2

ここでは、TideSDK に固有のものは何もありません。これは、イベント ループを中心に構築されたすべてのプログラムの一般的な問題です。つまり、ほぼすべての GUI アプリとネットワーク サーバーなどを意味します。

次の 3 つの標準的なソリューションがあります。

  1. 長いタスクを一連の小さなタスクに分割し、それぞれが次に実行されるようにスケジュールします。

  2. タスクを頻繁にイベント ループにコールバックさせます。

  3. タスクを並行して実行します。

doLater(func)最初の解決策として、ほとんどのイベントベースのフレームワークにはorのようなメソッドがありsetTimeout(func, 0)ます。そうでない場合は、少なくともイベント ループのキューにメッセージをポストする方法が必要であり、そのdoLater周りにかなり簡単に構築できます。この種の API は、C に似た言語で使用するのは恐ろしく、JS では、this/scoping ルールが奇妙であるという理由だけで少し厄介ですが、Python や他のほとんどの動的言語では、ほとんど問題はありません。

TideSDK はブラウザー JS エンジンを中心に構築されているため、ほぼ確実にこの最初のソリューションを提供します。

2 番目のソリューションは、協調スレッドレットまたは明示的なコルーチンのいずれかを中心に構築されたフレームワークに対してのみ意味があります。ただし、従来の Mac などの従来のシングルスレッド フレームワーク (したがって、最新の Win32 や wxWindows などのいくつかのクロスプラットフォーム フレームワーク) では、バックグラウンド ジョブの実行にこれを使用します。

1 つ目の問題は、再入可能性を慎重に処理する必要があることです (少なくともwxSafeYield少しは役に立ちます)。そうしないと、スレッドと同じ種類の問題が多数発生する可能性があります。頻繁に使用すると、無限再帰からスタック クラッシュが発生することがあります。もう 1 つの問題は、一度に重いバックグラウンド タスクが 1 つしかない場合にのみうまく機能することです。

フレームワークにこれを行う方法がある場合は、yieldToOtherTasksorのような関数があり、必要なprocessNextEventことは、時々それを呼び出すようにすることだけです。(ただし、 もある場合doLaterは、最初にそれを考慮する必要があります。) そのような方法がない場合、このソリューションはフレームワークに適していません。

threading.Thread3 番目の解決策は、またはを介し​​てタスクをスピンオフすることmultiprocessing.Processです。

この並列処理の問題は、安全に信号を送り、安全にデータを共有する方法を考え出さなければならないことです。一部のイベントループ フレームワークには、スレッド セーフな「doLater」または「postEvent」メソッドがあり、必要なシグナルが「タスク終了」のみであり、共有する必要があるデータがタスク起動パラメータと戻り値のみである場合、すべてが簡単。しかし、それが十分でない場合、事態は非常に複雑になる可能性があります。

また、何百もの実行時間の長いタスクがある場合、おそらくそれぞれのタスクにスレッドやプロセスは必要ありません。実際、スレッドまたはプロセスの固定サイズのプールが必要な場合は、タスクを十分に小さなサブタスクに分割して、相互に枯渇しないようにする必要があります。とにかくソリューション#1の作業。

ただし、スレッドまたはプロセスが最も単純なソリューションである場合もあります。

于 2012-11-21T00:35:48.823 に答える