ホームページ >バックエンド開発 >Python チュートリアル >サブプロセス PIPE からノンブロッキング読み取りを実行するにはどうすればよいですか?

サブプロセス PIPE からノンブロッキング読み取りを実行するにはどうすればよいですか?

Susan Sarandon
Susan Sarandonオリジナル
2024-12-22 15:13:10369ブラウズ

How to Perform Non-Blocking Reads from a Subprocess PIPE?

ノンブロッキング方式でのサブプロセス PIPE からの読み取り

サブプロセスを操作する場合、親プロセスの停止を避けるためにノンブロッキング読み取りを実行することが重要になる場合があります。子プロセスからの出力を待っている間。この問題は、subprocess.Popen を使用するときに発生します。利用可能なデータがない場合、readline() はブロックします。

従来のブロック手法

通常、開発者は次のコードを使用して読み取ります。サブプロセスの標準出力から:

p = subprocess.Popen('myprogram.exe', stdout = subprocess.PIPE)
output_str = p.stdout.readline()

ただし、データがない場合、このアプローチは実行をブロックします。

ノンブロッキング ソリューション

信頼性の高いクロスプラットフォーム ソリューションには、以下のコードに示すように Queue.get_nowait() の利用が含まれます。

import sys
from subprocess import PIPE, Popen
from threading  import Thread

try:
    from queue import Queue, Empty
except ImportError:
    from Queue import Queue, Empty  # python 2.x

ON_POSIX = 'posix' in sys.builtin_module_names

def enqueue_output(out, queue):
    for line in iter(out.readline, b''):
        queue.put(line)
    out.close()

p = Popen(['myprogram.exe'], stdout=PIPE, bufsize=1, close_fds=ON_POSIX)
q = Queue()
t = Thread(target=enqueue_output, args=(p.stdout, q))
t.daemon = True # thread dies with the program
t.start()

# ... do other things here

# read line without blocking
try:  line = q.get_nowait() # or q.get(timeout=.1)
except Empty:
    print('no output yet')
else: # got line
    # ... do something with line

このアプローチでは、別のスレッドを使用して出力行をキューに入れます。メインスレッドは、get_nowait() を使用して、ブロックせずにキューにデータが含まれているかどうかを確認できます。この移植可能なソリューションにより、さまざまなオペレーティング システムにわたるサブプロセス出力のノンブロッキング読み取りが可能になります。

以上がサブプロセス PIPE からノンブロッキング読み取りを実行するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。