Buradaki cevapların hiçbiri tüm ihtiyaçlarımı karşılamadı.
- Stdout için iş parçacığı yok (sıra yok, vb.)
- Başka şeyler olup olmadığını kontrol etmem gerektiğinden engelleme yok
- Akış çıktısı, bir günlük dosyasına yazma ve çıktının dize kopyasını döndürmek gibi birden çok şey yapmak için gerektiği gibi PIPE kullanın.
Küçük bir arka plan: Ben iş parçacığı havuzu yönetmek için bir ThreadPoolExecutor kullanıyorum, her biri bir alt işlem başlatmak ve onları eşzamanlılık çalışan. (Python2.7'de, ancak bu daha yeni 3.x sürümlerinde de çalışmalıdır). Ben iş parçacığı sadece çıkış toplama için mümkün olduğunca çok başka şeyler için mümkün olduğu gibi kullanmak istemiyorum (20 işlem bir havuz sadece çalıştırmak için 40 iş parçacıkları kullanıyor olacaktır; 1 işlem iş parçacığı için ve 1 stdout için ... ve stderr istiyorsanız daha fazla sanırım)
Ben bir çok istisna ve böyle burada sıyırma bu yüzden bu üretimde çalışan kod dayanmaktadır . Umarım kopyalayıp yapıştırmamı bozmadım. Ayrıca, geribildirim çok hoş geldiniz!
import time
import fcntl
import subprocess
import time
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
# Make stdout non-blocking when using read/readline
proc_stdout = proc.stdout
fl = fcntl.fcntl(proc_stdout, fcntl.F_GETFL)
fcntl.fcntl(proc_stdout, fcntl.F_SETFL, fl | os.O_NONBLOCK)
def handle_stdout(proc_stream, my_buffer, echo_streams=True, log_file=None):
"""A little inline function to handle the stdout business. """
# fcntl makes readline non-blocking so it raises an IOError when empty
try:
for s in iter(proc_stream.readline, ''): # replace '' with b'' for Python 3
my_buffer.append(s)
if echo_streams:
sys.stdout.write(s)
if log_file:
log_file.write(s)
except IOError:
pass
# The main loop while subprocess is running
stdout_parts = []
while proc.poll() is None:
handle_stdout(proc_stdout, stdout_parts)
# ...Check for other things here...
# For example, check a multiprocessor.Value('b') to proc.kill()
time.sleep(0.01)
# Not sure if this is needed, but run it again just to be sure we got it all?
handle_stdout(proc_stdout, stdout_parts)
stdout_str = "".join(stdout_parts) # Just to demo
Burada ekli yük var eminim ama benim durumumda bir endişe değildir. İşlevsel olarak ihtiyacım olanı yapar. Çözemediğim tek şey, bunun neden günlük iletileri için mükemmel çalıştığı, ancak bazı print
iletilerin daha sonra ve bir kerede ortaya çıktığını görüyorum .