12

アプリケーションが CPU を多用する処理を行っている間、GUI の応答性を維持することは、効果的な GUI プログラミングの課題の 1 つです。

wxPython でこれを行う方法についての良い議論があります。要約すると、3つの方法があります。

  1. スレッドを使用する
  2. wxYield を使用する
  3. 作業をチャンクし、IDLE イベント ハンドラーで実行します。

どの方法が最も効果的だと思いましたか? 他のフレームワーク (Qt、GTK、Windows API など) からのテクニックも歓迎します。

4

9 に答える 9

15

スレッド。必要なすべてのフレームワークで実行できるため、私が常に求めているものです。

そして、1 つの言語/フレームワークでのマルチスレッドと並列処理に慣れれば、すべてのフレームワークを使いこなせるようになります。

于 2008-09-29T14:40:08.217 に答える
7

確かにスレッド。なんで?未来はマルチコアです。ほとんどの新しい CPU には複数のコアが搭載されているか、コアが 1 つしかない場合でも、ハイパースレッディングをサポートしているため、複数のコアが搭載されているふりをしている可能性があります。マルチコア CPU を効果的に利用するには (Intel はそれほど遠くない将来に最大 32 コアにする予定です)、複数のスレッドが必要です。すべてを 1 つのメイン スレッド (通常は UI スレッドがメイン スレッド) で実行する場合、ユーザーは 8、16、および 1 日 32 コアの CPU を使用し、アプリケーションはこれらのコアを 1 つ以上使用することはなく、IOW の実行速度は非常に遅くなります。それが実行できるよりも。

実際、最近アプリを企画するなら、クラシカルなデザインはやめて、マスター/スレーブの関係を考えます。UI はマスターです。唯一のタスクは、ユーザーと対話することです。つまり、ユーザーにデータを表示し、ユーザー入力を収集します。アプリで「任意のデータを処理」する必要がある場合はいつでも (少量のデータでも、より重要な大きなデータでも)、任意の種類の「タスク」を作成し、このタスクをバックグラウンド スレッドに転送してスレッドにタスクを実行させ、 UI (たとえば、何パーセント完了したか、タスクがまだ実行中かどうかなど、UI に「進行中の作業インジケータ」を表示できます)。可能であれば、タスクを多数の小さな独立したサブタスクに分割し、複数のバックグラウンド プロセスを実行して、それぞれに 1 つのサブタスクを供給します。

実際、Apple や Microsoft などの企業は、まだ最もシングル スレッドの UI 自体をマルチスレッドにする方法をすでに計画しています。上記のアプローチでも、UI 自体がボトルネックになるという状況がいつか発生する可能性があります。バックグラウンド プロセスは、UI がユーザーにデータを提示したり、ユーザーに入力を求めたりするよりもはるかに高速にデータを処理できます。現在、多くの UI フレームワークはほとんどスレッド セーフではなく、多くはまったくスレッド セーフではありませんが、それは変わるでしょう。逐次処理 (次々にタスクを実行する) は死につつある設計であり、並列処理 (一度に多くのタスクを実行する) は将来の方向性です。グラフィックアダプターを見てください。最新の NVidia カードでさえ、GPU だけの MHz/GHz での処理速度を見ると、残念なパフォーマンスを示します。3D 計算に関しては、どうして CPU のがらくたを打ち負かすことができるのでしょうか? 単純:1 つのポリゴン ポイントまたは 1 つのテクスチャ ピクセルを次々に計算する代わりに、それらの多くを並行して (実際には同時に全体を) 計算することで、CPU を泣かせるスループットに到達します。たとえば、ATI X1900 (競合他社の名前も) には 48 個のシェーダー ユニットがあります。

于 2008-09-29T15:34:33.343 に答える
2

delayedresultはあなたが探しているものだと思います:

http://www.wxpython.org/docs/api/wx.lib.delayedresult-module.html

例については、wxpython デモを参照してください。

于 2008-12-18T18:40:36.587 に答える
1

アプリケーションに応じたスレッドまたはプロセス。実際には、GUI を独自のプログラムにして、実行する作業があるときに非同期呼び出しを他のプログラムに送信するのが最善の場合もあります。結果を監視するために GUI に複数のスレッドが存在することになりますが、実行中の作業が複雑で、GUI に直接接続されていない場合は、作業を簡素化できます。

于 2008-09-29T14:47:14.283 に答える
1

スレッド - シンプルな 2 層ビュー (GUI、アプリケーション ロジック) を使用してみましょう。

アプリケーション ロジックの作業は、別の Python スレッドで行う必要があります。GUI レイヤーまで伝達する必要がある非同期イベントの場合、wx のイベント システムを使用してカスタム イベントをポストします。wx イベントの投稿はスレッド セーフであるため、複数のコンテキストから投稿できる可能性があります。

別の方向 (GUI 入力イベントがアプリケーション ロジックをトリガーする) で作業すると、カスタム イベント システムをホーム ロールするのが最善であることがわかりました。Queue モジュールを使用して、スレッドセーフな方法でイベント オブジェクトをプッシュおよびポップします。次に、同期メンバー関数ごとに、同期関数オブジェクトとパラメーターをイベント キューにプッシュする非同期バージョンとペアにします。

これは、一度に 1 つのアプリケーション ロジック レベル操作しか実行できない場合に特に効果的です。このモデルの利点は、同期が単純であることです。各同期関数は、独自のコンテキスト内で、プリエンプションやハンドコーディングによる降伏を心配することなく、最初から最後まで順番に動作します。重要なセクションを保護するためにロックは必要ありません。関数の最後に、操作が完了したことを示すイベントを GUI レイヤーに送信します。

これを拡張して複数のアプリケーションレベルのスレッドが存在できるようにすることもできますが、同期に関する通常の問題が再び発生します。

編集- これの美しさについて言及するのを忘れていました。それは、GUI コードからアプリケーション ロジックを完全に切り離すことができるということです。モジュール性は、別のフレームワークを使用するか、アプリのコマンドライン バージョンを提供することを決定した場合に役立ちます。これを行うには、GUI レイヤーによって実装される中間イベント ディスパッチャー (アプリケーション レベル -> GUI) が必要です。

于 2008-09-29T18:53:30.743 に答える
0

この回答は、Pythonに関するOPの質問には当てはまりませんが、よりメタレスポンスです。

簡単な方法はスレッドです。ただし、すべてのプラットフォームがプリエンプティブ スレッドを備えているわけではありません (BREW、その他の組み込みシステムなど)。

BREW でスレッドを使用する場合のもう 1 つの問題は、C++ スタック オブジェクトがクリーンアップされないことです。そのため、単純にスレッドを強制終了すると、簡単にメモリ リークが発生します。

于 2008-09-29T15:17:27.550 に答える
0

GUI のメイン イベント ループがブロックされないように、スレッドを使用します。

于 2008-09-29T15:17:47.300 に答える
0

Win32 用の Qt/C++ での作業。

主要な作業単位をさまざまなプロセスに分割します。GUI は別のプロセスとして実行され、必要に応じて「ワーカー」プロセスにコマンドを送信したり、データを受信したりできます。今日のマルチコアの世界でうまく機能します。

于 2008-09-29T14:45:16.160 に答える
0

一部のタイプの操作では、個別のプロセスを使用することが非常に理にかなっています。昔は、プロセスの生成には多くのオーバーヘッドが発生していました。最新のハードウェアでは、このオーバーヘッドは画面上のわずかな時間でさえほとんどありません。これは、実行時間の長いプロセスを生成している場合に特に当てはまります。

(議論の余地がある) 利点の 1 つは、スレッドよりも概念モデルが単純であり、保守しやすいコードにつながる可能性があることです。また、GUI を使用せずにこれらの外部プロセスを実行するテスト スクリプトを作成できるため、コードのテストが容易になります。それが主な利点であると主張する人さえいるかもしれません.

私がかつて取り組んだコードの場合、スレッドから別のプロセスに切り替えることで、5000 行を超えるコードの純削減につながり、同時に GUI の応答性が向上し、コードの保守とテストが容易になり、すべて改善されました。全体的なパフォーマンスの合計。

于 2008-09-29T15:20:07.450 に答える