[英]How can I track time a python subprocess while it's running dynamically and update a database?
I have a subprocess that encodes a video , and what I would love to do is update at database record with the time it is taking to encode the video (so I can print it out in ajax on a web page) 我有一个对视频进行编码的子流程,我想做的是在数据库记录中更新对视频进行编码所花费的时间(因此我可以将其以ajax格式打印在网页上)
I am very close - this code I have so far updates the database and encodes the video - but the process/loop gets stuck on the final db.commit() and never exits the while True: loop. 我非常接近-到目前为止,我已使用此代码更新数据库并对视频进行编码-但进程/循环卡在最终的db.commit()中,并且永远不会退出while True:循环。 Is there a better way to do this?
有一个更好的方法吗? Here is the code I am tinkering with:
这是我要修改的代码:
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)
You're right, because you have no way of exiting your infinite loop, it will just spin forever. 您说对了,因为您无法退出无限循环,它将永远旋转。 What you need to do it call check p.poll() to see if the process has exited (it will return none if it hasn't).
您需要做的是调用check p.poll()来查看该进程是否已经退出(如果尚未退出,则不返回任何内容)。 So, something like:
因此,类似:
while True:
if p.poll():
break
... other stuff...
or better yet: 或更好:
while p.poll() == None:
.... other stuff....
will cause your loop to terminate when the subprocess is complete. 当子进程完成时,将导致您的循环终止。 then you can call p.communicate() to get the output.
然后您可以调用p.communicate()获取输出。
I would also suggest using a sleep or delay in there so that your loop doesn't spin using 100% of your CPU. 我还建议在其中使用睡眠或延迟,以免循环使用100%的CPU。 Only check and update your database every second, not continuously.
仅每秒检查一次并更新您的数据库,而不是连续进行。 So:
所以:
while p.poll() == None:
time.sleep(1)
...other stuff...
In addition to the infinite loop issue pointed out by @clemej , there is also a possibility of a deadlock because you don't read from p.stdout
pipe in the loop despite stdout=subprocess.PIPE
ie, while p.poll() is None:
will also loop forever if avconv
generates enough output to fill its stdout OS pipe buffer. 除了@clemej指出的无限循环问题外 ,还有死锁的可能,因为尽管
stdout=subprocess.PIPE
p.stdout
您也不会从循环中的p.stdout
管道读取,即while p.poll() is None:
如果avconv
生成足够的输出以填充其stdout OS管道缓冲区,也将永远循环。
Also, I don't see the point to update the progress time in the database while the process is still running. 另外,在进程仍在运行时,我看不到在数据库中更新进度时间的意义。 All you need is two records:
您只需要两条记录:
video_id, start_time # running jobs
video_id, end_time # finished jobs
If the job is not finished then the progress time is current_server_time - start_time
. 如果作业未完成,则进度时间为
current_server_time - start_time
。
If you don't need the output then you could redirect it to devnull: 如果不需要输出,则可以将其重定向到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.