【问题标题】:Python kill a subprocess(that starts another process) and start it againPython杀死一个子进程(启动另一个进程)并再次启动它
【发布时间】:2014-10-23 11:27:26
【问题描述】:

我正在尝试制作一个启动程序 livestreamer(启动程序 mplayer)的 python 脚本,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 的命令。

【问题讨论】:

  • 运行救生艇后,您可以运行另一个命令来获取救生艇的 pid。然后在 10 秒后您可以将其杀死。 :)
  • 你的解决方案可以工作,但不是很灵活,我希望你的系统上没有其他东西会调用 mplayer 因为 killall 会杀死所有这些:)
  • 是的,我理解,但这在我的情况下不是问题,但可能适用于其他情况。 :)

标签: python linux subprocess


【解决方案1】:

在您的代码中,您会杀死 livestreamer 而不是 mplayer,因此 mplayer 将继续运行。

通过在您的子进程上使用 kill 您发送信号 SIGKILL ,除非子进程确实处理信号中断,否则它将简单地快速关闭自己并且不会杀死自己的子进程,因此 mplayer 将存活(并可能成为僵尸进程)。

你没有引用你的子进程子 'mplayer' 但如果你能得到他的 PID 你可以用 os.kill(...) 杀死它

os.kill(process_pid, signal.SIGTERM)

【讨论】:

  • 你知道我如何从 mplayer 获取 PID 吗?目前处理 mplayer 的是 livestreamer,livestreamer 通过读取 livestreamers 配置启动 mplayer(您可以在代码中播种)。通常如果你想用 mplayer 启动 livestreamer,你必须发出命令livestreamer someurl --player mplayer。它不是像进程树一样创建,livestreamer 是父进程,mplayer 是子进程,我可以杀死整个树吗?
  • 您可以通过“tasklist”(Windows)或“ps”(Unix)获取正在运行的进程列表和pid。
  • stackoverflow.com/a/6481337/3816698 使用 Unix 脚本的优雅解决方案。
  • 我尝试过这种方式,但只是让它变得比需要的更复杂。但是我想出了一个解决方案,请参阅原始帖子。 :)
【解决方案2】:

使用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()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-19
    • 2016-04-21
    • 2015-03-22
    • 2022-06-14
    • 1970-01-01
    • 1970-01-01
    • 2018-11-10
    • 1970-01-01
    相关资源
    最近更新 更多