質問

GUIの応答性を維持しながら、アプリケーションがCPUを大量に処理することは、効果的なGUIプログラミングの課題の1つです。

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

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

どの方法が最も効果的であるとあなたがわかりましたか?他のフレームワーク(Qt、GTK、Windows APIなど)の手法も歓迎します。

役に立ちましたか?

解決

スレッド。あなたが必要とするすべてのフレームワークでそれを行うことができるので、それらは私がいつも求めているものです。

そして、1つの言語/フレームワークでマルチスレッドと並列処理に慣れたら、すべてのフレームワークに慣れます。

他のヒント

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

実際、最近のアプリケーションを計画している場合、古典的なデザインから離れて、マスター/スレーブの関係を考えます。 UIがマスターであり、唯一のタスクはユーザーと対話することです。それはユーザーにデータを表示し、ユーザー入力を収集しています。アプリが「データを処理する」必要があるときはいつでも(少量であっても、より重要な大きなものであっても)、「タスク」を作成します。あらゆる種類の、このタスクをバックグラウンドスレッドに転送し、スレッドにタスクを実行させて、UIにフィードバックを提供します(たとえば、タスクが完了した割合、またはタスクがまだ実行中かどうかなど、UIは&quot ;作業中インジケータ")。可能であれば、タスクを多数の独立した小さなサブタスクに分割し、複数のバックグラウンドプロセスを実行して、それぞれに1つのサブタスクを供給します。そうすれば、アプリケーションはマルチコアの恩恵を本当に受け、CPUのコアが増えるほど高速になります。

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

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

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

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

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

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

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

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

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

これをスケーリングして、複数のアプリケーションレベルのスレッドを存在させることができますが、同期に関する通常の懸念が再表示されます。

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

Win32用Qt / C ++の使用

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

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

簡単な方法はスレッドです。ただし、すべてのプラットフォームにプリエンプティブスレッド(たとえば、BREW、その他の組み込みシステム)があるわけではありません。可能であれば、単に作業をチャンクして、IDLEイベントハンドラーで実行します。

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

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

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

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

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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top