[英]How do I get data from a subprocess PIPE while the subprocess is running in Python?
[英]How can I track time a python subprocess while it's running dynamically and update a database?
我有一個對視頻進行編碼的子流程,我想做的是在數據庫記錄中更新對視頻進行編碼所花費的時間(因此我可以將其以ajax格式打印在網頁上)
我非常接近-到目前為止,我已使用此代碼更新數據庫並對視頻進行編碼-但進程/循環卡在最終的db.commit()中,並且永遠不會退出while True:循環。 有一個更好的方法嗎? 這是我要修改的代碼:
time_start = time.time()
try:
p = subprocess.Popen(["avconv" , "-y" , "-t" , "-i" , images , "-i" , music_file , video_filename], universal_newlines=True, stdout=subprocess.PIPE)
while True:
time_now = time.time()
elapsed_time = time_now - time_start
progress_time = "ENCODING TIME" + str(int(elapsed_time)) + " Seconds "
cursor.execute("UPDATE video SET status = %s WHERE id = %s" ,[progress_time , video_id] )
db.commit()
out, err = p.communicate()
retcode = p.wait()
except IOError:
pass
else:
print "] ENCODING OF VIDEO FINISHED:" + str(retcode)
您說對了,因為您無法退出無限循環,它將永遠旋轉。 您需要做的是調用check p.poll()來查看該進程是否已經退出(如果尚未退出,則不返回任何內容)。 因此,類似:
while True:
if p.poll():
break
... other stuff...
或更好:
while p.poll() == None:
.... other stuff....
當子進程完成時,將導致您的循環終止。 然后您可以調用p.communicate()獲取輸出。
我還建議在其中使用睡眠或延遲,以免循環使用100%的CPU。 僅每秒檢查一次並更新您的數據庫,而不是連續進行。 所以:
while p.poll() == None:
time.sleep(1)
...other stuff...
除了@clemej指出的無限循環問題外 ,還有死鎖的可能,因為盡管stdout=subprocess.PIPE
p.stdout
您也不會從循環中的p.stdout
管道讀取,即while p.poll() is None:
如果avconv
生成足夠的輸出以填充其stdout OS管道緩沖區,也將永遠循環。
另外,在進程仍在運行時,我看不到在數據庫中更新進度時間的意義。 您只需要兩條記錄:
video_id, start_time # running jobs
video_id, end_time # finished jobs
如果作業未完成,則進度時間為current_server_time - start_time
。
如果不需要輸出,則可以將其重定向到devnull:
import os
from subprocess import call
try:
from subprocess import DEVNULL # Python 3
except ImportError:
DEVNULL = open(os.devnull, 'r+b', 0)
start_time = utcnow()
try:
returncode = call(["avconv", "-y", "-t", "-i", images,
"-i", music_file, video_filename],
stdin=DEVNULL, stdout=DEVNULL, stderr=DEVNULL)
finally:
end_time = utcnow()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.