ホームページ >バックエンド開発 >Python チュートリアル >プロセス出力の読み取り時に Python プログラムがハングしないようにするにはどうすればよいですか?

プロセス出力の読み取り時に Python プログラムがハングしないようにするにはどうすればよいですか?

Susan Sarandon
Susan Sarandonオリジナル
2024-11-02 13:54:29529ブラウズ

How to Avoid Python Programs from Hanging When Reading Process Output?

ハングせずに Python でのプロセス出力の読み取りを停止しますか?

問題:

Python プログラムは外部と対話する必要があります継続的に出力を生成するプロセス (「トップ」など)。ただし、出力を直接読み取るだけでは、プログラムが無期限にハングする可能性があります。

解決策:

ハングを防ぐには、次の場合に非ブロッキングまたは非同期メカニズムを採用することが不可欠です。読み取りプロセスの出力。以下に考えられるアプローチをいくつか示します。

スプール一時ファイル (推奨)

このメソッドは、専用のファイル オブジェクトを利用してプロセス出力を保存します。

#! /usr/bin/env python<br>import subprocess<br>import tempfile<br>import time</p>
<p>def main():</p>
<pre class="brush:php;toolbar:false"># Open a temporary file (automatically deleted on closure)
f = tempfile.TemporaryFile()

# Start the process and redirect stdout to the file
p = subprocess.Popen(["top"], stdout=f)

# Wait for a specified duration
time.sleep(2)

# Kill the process
p.terminate()
p.wait()

# Rewind and read the captured output from the file
f.seek(0)
output = f.read()

# Print the output
print(output)
f.close()

if name == "__main__":

main()

スレッドベースの出力読み取り

このアプローチでは、別のスレッドを使用してプロセス出力を継続的に読み取ります。メインスレッドは他のタスクを続行します。

コレクションのインポート<br>サブプロセスのインポート<br>スレッドのインポート<br>インポート時間</p>
<p>def read_output(process, append):</p>
<pre class="brush:php;toolbar:false">for line in iter(process.stdout.readline, ""):
    append(line)

def main():

# Start the process and redirect stdout
process = subprocess.Popen(["top"], stdout=subprocess.PIPE, close_fds=True)

# Create a thread for output reading
q = collections.deque(maxlen=200)
t = threading.Thread(target=read_output, args=(process, q.append))
t.daemon = True
t.start()

# Wait for the specified duration
time.sleep(2)

# Print the saved output
print(''.join(q))

if name == "__main__":

main()

signal.alarm() (Unix のみ)

このメソッドは、Unix シグナルを使用して、すべての出力が読み取られたかどうかに関係なく、指定されたタイムアウト後にプロセスを終了します。

インポート コレクション<br>インポート シグナル<br>インポート サブプロセス</p>
<p>クラス Alarm(Exception):</p>
<pre class="brush:php;toolbar:false">pass

def Alarm_handler(signum, Frame):

raise Alarm

def main():

# Start the process and redirect stdout
process = subprocess.Popen(["top"], stdout=subprocess.PIPE, close_fds=True)

# Set signal handler
signal.signal(signal.SIGALRM, alarm_handler)
signal.alarm(2)

try:
    # Read and save a specified number of lines
    q = collections.deque(maxlen=200)
    for line in iter(process.stdout.readline, ""):
        q.append(line)
    signal.alarm(0)  # Cancel alarm
except Alarm:
    process.terminate()
finally:
    # Print the saved output
    print(''.join(q))

if name == "__main__":

main()

threading.Timer

このアプローチでは、タイマーを使用して、指定されたタイムアウト後にプロセスを終了します。 Unix と Windows システムの両方で動作します。

コレクションのインポート<br>サブプロセスのインポート<br>スレッドのインポート</p>
<p>def main():</p>
<pre class="brush:php;toolbar:false"># Start the process and redirect stdout
process = subprocess.Popen(["top"], stdout=subprocess.PIPE, close_fds=True)

# Create a timer for process termination
timer = threading.Timer(2, process.terminate)
timer.start()

# Read and save a specified number of lines
q = collections.deque(maxlen=200)
for line in iter(process.stdout.readline, ""):
    q.append(line)
timer.cancel()

# Print the saved output
print(''.join(q))

if name == "__main__":

main()

スレッドなし、シグナルなし

このメソッドはプロセス出力をチェックし、指定されたタイムアウトを超えた場合にプロセスを強制終了する単純な時間ベースのループ。


インポート コレクション
インポート サブプロセス
インポート sys

インポート時間

def main():
args = sys.argv[1:]
if not args:
    args = ['top']

# Start the process and redirect stdout
process = subprocess.Popen(args, stdout=subprocess.PIPE, close_fds=True)

# Save a specified number of lines
q = collections.deque(maxlen=200)

# Set a timeout duration
timeout = 2

now = start = time.time()
while (now - start) < timeout:
    line = process.stdout.readline()
    if not line:
        break
    q.append(line)
    now = time.time()
else:  # On timeout
    process.terminate()

# Print the saved output
print(''.join(q))

if name

== "__main__":
main()

注:

保存される行数は、deque データ構造の 'maxlen' パラメーターを設定することで、必要に応じて調整できます。

以上がプロセス出力の読み取り時に Python プログラムがハングしないようにするにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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