出力のキャプチャとバックグラウンドでの実行の両方 threading
この回答で述べたように、で出力をキャプチャしstdout=
てからしようとするread()
と、プロセスがブロックされます。
ただし、これが必要な場合があります。たとえば、それらの間のポートを介して通信する2つのプロセスを起動し、それらの標準出力をログファイルと標準出力に保存したいと考えました。
threading
モジュールは、私たちはそれを行うことができます。
まず、この質問で出力リダイレクトの部分だけを行う方法を見てください:Python Popen:stdoutとログファイルに同時に書き込み
次に:
main.py
#!/usr/bin/env python3
import os
import subprocess
import sys
import threading
def output_reader(proc, file):
while True:
byte = proc.stdout.read(1)
if byte:
sys.stdout.buffer.write(byte)
sys.stdout.flush()
file.buffer.write(byte)
else:
break
with subprocess.Popen(['./sleep.py', '0'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) as proc1, \
subprocess.Popen(['./sleep.py', '10'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) as proc2, \
open('log1.log', 'w') as file1, \
open('log2.log', 'w') as file2:
t1 = threading.Thread(target=output_reader, args=(proc1, file1))
t2 = threading.Thread(target=output_reader, args=(proc2, file2))
t1.start()
t2.start()
t1.join()
t2.join()
sleep.py
#!/usr/bin/env python3
import sys
import time
for i in range(4):
print(i + int(sys.argv[1]))
sys.stdout.flush()
time.sleep(0.5)
実行後:
./main.py
stdoutは、2行ごとに0.5秒ごとに更新されます。
0
10
1
11
2
12
3
13
各ログファイルには、特定のプロセスの各ログが含まれています。
触発:https : //eli.thegreenplace.net/2017/interacting-with-a-long-running-child-process-in-python/
Ubuntu 18.04、Python 3.6.7でテスト済み。