0

これらの質問をいくつか見てきましたが、まだ本当の答えを見つけていません。

gstreamer パイプを起動し、送り返すデータをリッスンするアプリケーションがあります。

私がベースにしたサンプル アプリケーションでは、次のコードで終了します。

gtk.main()

gtk ウィンドウはありませんが、このコードによって実行が継続されます。それがなければ、プログラムは終了します。

今、私は を使用した構成について読みましwhile True:たが、それらにはsleepコマンドが含まれています。間違っていなければ、スリープ中にアプリケーションがフリーズする原因となります...

gtk.main() を使用せずに、より良い方法はありますか?

4

2 に答える 2

3

gtk.main()イベントループを実行します。内部には次のようなコードがあるため、終了せず、何もせずにフリーズすることもありません。

while True:
    timeout = timers.earliest() - datetime.now()
    try:
        message = wait_for_next_gui_message(timeout)
    except TimeoutError:
        handle_any_expired_timers()
    else:
        handle_message(message)

そのwait_for_next_gui_message関数は、X11、WindowServer、Windows の名前のないものなどを待って、「ユーザーがボタンをクリックしました」や「ユーザーが ctrl-Q を押した」などのメッセージを配信する、さまざまなプラットフォーム固有の関数のラッパーです。

、などで呼び出しhttp.serve_forever()または類似した場合、はすべてのソケットのリストである のようなものをラップする関数であることを除いて、まったく同じことを行います。twistedHTTPServerwait_for_next_network_message(sources, timeout)select.selectsources

gstreamer パイプでリッスンしている場合、 はsourcesそのパイプであり、wait_for_next関数はselect.select.

もちろん、 のようなネットワーク フレームワークを使用することもできますtwisted


ただし、このようにアプリを設計する必要はありません。複数のソースを待つ必要がない場合は、次のようにブロックできます。

while True:
    data = pipe.read()
    handle_data(data)

パイプがノンブロッキングに設定されていないことを確認してください。よくわからない場合はsetblocking、ソケット、fcntlUnix パイプ、または Windows パイプで頭のてっぺんから覚えていない何かを使用して確認できます。

実際、複数のソースを待機する必要がある場合でも、各ソースのブロッキング ループを個別のスレッド (またはプロセス) に配置することで、これを行うことができます。これは数千のソケットでは機能しませんが (その場合はスレッドの代わりに greenlet を使用できます)、3 つまたは 30 の場合は問題ありません。

于 2013-02-15T22:42:12.807 に答える
1

私は Cmd クラスのファンになりました。プログラムのシェルプロンプトを表示し、入力を待っている間ループにとどまります。ドキュメントへのリンクは次のとおりです。それはあなたが望むことをするかもしれません。

于 2013-02-15T22:00:40.293 に答える