2

PILを使用してスクリーンショットなどを撮るなど、Pythonでいくつかのウィンドウを自動化しています。問題は、時々、ある機能の奥深くで、time.sleep(1)私がインターフェイスしている GUI アプリがその瞬間フリーズすることです。time.sleepこれは、他の場所で実行してもフリーズしないという奇妙な原因です。フリーズの原因とそうでないものを正確に特定することはできませんでした.メインスレッド以外のスレッドとメインスレッドの両方で発生しました。

何か案は?Python が行っていることをすべて停止させ、対象の UI を回復させて更新し、入力を処理してから、Python に戻すには、「チルアウト」関数のようなものが必要だと思います。それを行う機能は何ですか?(windowsSleep関数は python の と同じように動作するようtime.sleepです。)

4

3 に答える 3

1

Python が何をしていても停止し、対象の UI を回復させて更新し、入力を処理してから、Python に戻すには、「チルアウト」関数のようなものが必要だと思います。それを行う機能は何ですか?

呼び出しsleep()(そのバリアント) は、呼び出し元のスレッドの実行をブロックします。これは、そのスレッドでレスポンシブ UI を使用したい場合に行う最後のことです。簡単に言うと、寝たら何もできない!

ユーザー インターフェイスが応答しない場合は、UI を処理するスレッドで実行時間の長いタスクが実行されているか、UI スレッドがブロックされていることを示します。したがって、ロジックをたどると、1 秒間のスリープ (適切なスリープではなく、実際には居眠りです!) が UI のハングを引き起こしている場合、それらは UI と同じスレッド、または UI が動作しているスレッドで発生している必要があります。待っている。

あなたが PIL をどのように使用しているか、また、スクレイピングしている画像のアプリとどのようにやり取りしているかはよくわかりませんが、他のプロセスに注入している可能性はあまりないようです。だから私はそのプロセスがあなたのスレッドを待っていると思います。そうであれば、問題を解決する近道はありません。単純に、何をしていても時間を短縮する必要があります。電話sleep()は事態を悪化させるだけです。

電話SwitchToThread()してもあまり役に立ちません。それが行うことは、別のスレッドの実行を許可することだけです (待機中のスレッドが実行の準備ができている場合)。ただし、現在のスレッドを実行したい場合。いずれにせよ、システムはスレッドが実行を望んでいることを認識し、やがて再びスケジュールを設定するため、大きな違いはありません。

肝心なのは、そのプロセスをブロックしている UI プロセスでコードを実行していることです。干渉を最小限に抑えるために、できるだけ早くそれを実現する必要があります。

于 2011-03-17T23:05:27.007 に答える
1

現在のスレッドをスリープさせたくない場合は、アプリケーションにメッセージを処理する機会を与えてください。

アプリケーションのメイン メッセージ ポンプに委譲するのは難しいため、従来、実行時間の長いタスクのほとんどは、独自の一時的なメッセージ ポンプを呼び出していました。

def process_messages():
    msg = wintypes.MSG ()
    while user32.GetMessageA (byref (msg), None, 0, 0) != 0:  
        user32.TranslateMessage (byref (msg))
        user32.DispatchMessageA (byref (msg))

Microsoft に祝福されたバージョンはこちら. コードは、スレッドを起動したアプリケーションのイベント ループにイベントを配信し、イベント キューが空になると戻ります。

機能の実装について Python とサードパーティのライブラリを少し調べましたが、そのようなクイック検索では見つかりませんでした。

つまり、process_messages()Visual Basic や他のいくつかの Windows 専用言語で行われたように、独自の関数の呼び出しで上記のようなことを行う必要があり、 sleep().

psメッセージポンプを微調整して、待っているタスクが完了するまでメッセージをポンプすることができます。

于 2011-03-19T01:18:12.603 に答える
0

ああSwitchToThread、有望そうです。または Python 用語では、ctypes.windll.kernel32.SwitchToThread().

編集:うーん、それをまったくしていないようです...

于 2011-03-17T22:48:25.030 に答える