2

同じアプリケーションで Twisted と GTK+ を使いたいです。私は gtk2reactor を使用しており、すべてのコードを適切に非ブロック化しており、一般的にはかなりうまく機能しています。

ただし、(HTTP) ダウンロードを実行すると、GUI が応答しなくなり、遅延が発生します。それはあたかも何かがねじれたブロックの中にあるかのようで (非常に短い時間の間)、reactor は GTK イベントを頻繁に処理しません。基本的に、私は使用しています:

factory = twc.HTTPDownloader(url, filename)
reactor.connectTCP(host, port, factory)

問題を示すための小さな PyGtk プログラムを次に示します。アニメーションを表示するダミーの進行状況バーしかありませんが、本格的なプログラムでも問題は顕著です。ダウンロードが実行されている限り、スクロールまたは GtkNotebook タブ間の切り替え時に顕著な遅延があります。

これは予想どおりですか、それとも何か間違っていますか? 以前に GTK + Twisted アプリケーションを実行したことがありますが、これに気づいたことはありませんでしたが、以前はより大きなファイル (〜 300 MB) を転送したこともありませんでした。もしかしたら、twisted が大きすぎるチャンク サイズを選択し、メイン ループに制御を戻す前に長時間 (~100 ミリ秒?) ビジーのままになるのでしょうか? 代わりに、GTK とツイスト ループに別のスレッドを使用する必要がありますか?

4

1 に答える 1

1

この問題を解決するためのアドバイスをする前に、このようなパフォーマンスの問題に直面したときはいつでも、アプリケーションをプロファイリングして、何が最も時間がかかっているかを確認する必要があることに注意してください。次のようなプロファイラーを使用できますcProfile。または、おそらくstatprof、またはおそらくTwisted のリアクターをブロックしているものを特定するためのGeoff Greer によるこのクールなハックです。客観的なデータは常に推測よりも優れており、特定のデータは特定の環境からのみ取得できます。

そうは言っても、私はあなたにいくつかの推測があります。おそらく、ここでの問題はファイル I/O です。ノンブロッキング ファイル I/O は Twisted にとってはちょっと厄介なところです。なぜなら、基本的にスレッドをスピンアップするだけでは実現できないからです。 API。それにもかかわらず、Twistedに、このスレッド化部分を抽象化する何かが必要です。

HTTPDownloader、具体的には、reactor がスタックして GUI がフリーズするファイル書き込みをブロックします。オーバーライドpagePartして、ブロックしないことを行うことができます。ただし、これは、オブジェクトの属性でフロー制御を行う必要があることを意味します-たとえば、それを指示します-または、遅いディスクを使用している場合、そのファイルのすべてをメモリにバッファリングすることになる可能性があります。HTTPPageDownloadertransportpauseProducing

Agent新しいAPIを使用すると、これらすべてがより簡単になる場合があります。独自のノンブロッキング ファイル I/O を実行する必要がありますが、少なくともAPIdeliverBodyは、いくつかの異なるものをサブクラス化したり、抽象化のいくつかのレイヤー ( 、、、) にアクセスします。transportpauseProducingClientFactoryHTTPClientFactoryHTTPDownloaderHTTPPageDownloader

Twisted ではフロー制御をより簡単に管理できるはずだとわかっていますが、セットアップが少し面倒で申し訳ありません。私は知っています、そして私たちはそれに取り組んでいます。

于 2013-03-31T22:12:56.913 に答える