![](/img/trans.png)
[英]Read from a named pipe in two parts in python: First python, then subprocess
[英]python subprocess: read from pipe without closing it
我有一個將連續字節流寫入stdout的進程。 我有另一個過程,它從第一個過程的標准輸出中讀取,然后完成。 但是我發現第二個進程完成時,它關閉了管道(我認為),因此進程1停止運行。
我嘗試了兩種不同的方式:
在外殼1中:
# make fifo
mkfifo /tmp/camera
# stream video from my webcam to the pipe
ffmpeg -y -f v4l2 -r 10 -i /dev/video0 -f avi /tmp/camera
在外殼2中:
# attach to pipe and take a snapshot
rrmpeg -y -r 1 -f avi -i /tmp/camera -vframes 1 -s 160x120 -f image2 image1.jpg
我也在shell 2中嘗試過,結果相同:
tail -f /tmp/camera
當外殼2中的進程停止時,它將終止進程1。為什么?
我嘗試的第二件事是使用python子進程:
from subprocess import Popen, PIPE
import shlex, time
stream = Popen(shlex.split("ffmpeg -y -f v4l2 -r 10 -i /dev/video0 -f avi -"), stdout=PIPE)
while True:
time.sleep(3)
snap = Popen(shlex.split("rrmpeg -y -r 1 -f avi -i - -vframes 1 -s 160x120 -f image2 image1.jpg"), stdin=stream.stdout)
它在循環中第一次起作用,但是當snap
進程超出范圍時, stream
進程終止。
有什么方法可以在不關閉進程1的情況下讀取其中的某些流?
是的,有一種方法可以永遠繼續管道編寫器。 為此,您必須確保
第二個選項不是那么簡單(無需更改/檢查編寫器的源代碼),因為沒有讀取器的管道上的write()不會阻塞(一旦讀取器在那里)。
對於第一個選項,請確保您的第一個閱讀器打開了fifo / pipe,不從中讀取任何內容,然后永遠阻止/休眠某些東西而不會死。
讓任何連續的讀者來做這項工作。 他們可以打開fifo(命名管道),也可以從讀取端打開的過程中分叉(它們繼承了filedescriptor)。
這樣,就不會生成SIGPIPE,並且一旦管道緩沖區已滿,write()將阻止編寫器。
man 7 pipe
告訴你更多。
(注意:如果write()阻止意外的長時,某些程序可能會感到困惑。例如,一些經常掛在牆上的應用程序。)
關於“當shell 2中的進程停止時,它殺死進程1。為什么?” :
進程1可能被SIGPIPE殺死了(我沒有檢查源代碼),當它在沒有讀取器的管道上嘗試write()
時,它將獲得該信息。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.