Python 终止子进程(启动另一个进程)并重新启动它
我正在尝试写一个Python脚本,这个脚本会启动一个叫做livestreamer的程序(它会再启动一个叫做mplayer的程序),然后在10秒后结束这个程序或者它的子进程。下面是我现在的代码,但它不太好用,我觉得我知道问题出在哪里,但不知道怎么解决。
我认为问题在于,子进程启动了livestreamer,而livestreamer又启动了mplayer。Python并不知道mplayer的存在,所以无法关闭它。我该如何在10秒后同时结束livestreamer和mplayer,然后再以循环的方式重新启动它们呢?我使用的是Ubuntu 14.04(Linux)和Python 2.7.6。
import subprocess
import time
import os
import sys
import signal
url = "http://new.livestream.com/accounts/398160/events/3155348"
home = os.environ['HOME']
if not os.geteuid() == 0:
if not os.path.exists('/%s/.config/livestreamer' % home):
os.makedirs('/%s/.config/livestreamer' % home)
lscfg = open('%s/.config/livestreamer/config' % home, 'w+')
lscfg.write("player=mplayer -geometry 0%:0% -nomouseinput -loop 100 -noborder -fixed-vo")
lscfg.close()
cmd = "livestreamer %s best --player-continuous-http --player-no-close" % url
while True:
proc1 = subprocess.Popen(cmd.split(), shell=False)
time.sleep(10)
proc1.kill()
解决方案:
import subprocess
import time
import os
import sys
import signal
url = "http://new.livestream.com/accounts/398160/events/3155348"
home = os.environ['HOME']
if not os.geteuid() == 0:
if not os.path.exists('/%s/.config/livestreamer' % home):
os.makedirs('/%s/.config/livestreamer' % home)
lscfg = open('%s/.config/livestreamer/config' % home, 'w+')
lscfg.write("player=mplayer -geometry 0%:0% -nomouseinput -loop 100 -noborder -fixed-vo")
lscfg.close()
cmd = "livestreamer %s best --player-continuous-http --player-no-close" % url
#restarting the player every 10th minute to catch up on possible delay
while True:
proc1 = subprocess.Popen(cmd.split(), shell=False)
time.sleep(600)
os.system("killall -9 mplayer")
proc1.kill()
如你所见,os.system("killall -9 mplayer")是用来结束mplayer进程的命令。
2 个回答
0
在你的代码中,你结束了livestreamer这个程序,但没有结束mplayer,所以mplayer会继续运行。
当你对你的子进程使用kill命令时,你实际上是发送了一个叫做SIGKILL的信号。除非这个子进程能够处理这个信号,否则它会很快关闭自己,但不会去结束它自己创建的子进程,所以mplayer会继续运行(可能会变成一个僵尸进程)。
你没有mplayer这个子进程的引用,但如果你能找到它的PID(进程ID),你就可以用os.kill(...)来结束它。
os.kill(process_pid, signal.SIGTERM)
0
使用 os.system("killall -9 mplayer")
是个简单的解决办法。不过要注意,这个方法会把所有的 mplayer 进程都杀掉。在我的情况下这没问题,但在其他情况下可能会有问题。
while True:
proc1 = subprocess.Popen(cmd.split(), shell=False)
time.sleep(600)
os.system("killall -9 mplayer")
proc1.kill()