检查进程是否仍在运行

2024-03-29 03:02:15 发布

您现在位置:Python中文网/ 问答频道 /正文

我有以下问题:

我需要我的Python脚本运行bash脚本。如果bash脚本运行超过10秒,我需要终止它。到目前为止,我得到的是:

cmd = ["bash", "script.sh", self.get_script_path()]
process = subprocess.Popen(cmd)

time.sleep(10)  # process running here...

procinfo = psutil.Process(process.pid)
children = procinfo.children(recursive=True)
for child in children:
    os.kill(child.pid, signal.SIGKILL)

我担心的是这种情况:bash脚本在1秒内完成,释放其PID,系统将PID传递给另一个进程。10秒后,我杀死了PID,我认为它属于我的脚本,但它不是真的,我杀死了一些其他进程。脚本需要以根用户身份运行,因为我需要在其中使用chroot。在

有什么想法吗?在


Tags: pathself脚本cmdbashchildget进程
3条回答

由于您已经在使用psutil,我建议您将对subprocess模块的调用替换为对{a1}的调用。此类具有相同的subprocess.Popen接口,但提供psutil.Process的所有功能。在

还要注意,psutil库已经预先检查PID重用了,至少有很多方法包括terminate和{}(只需阅读documentation for ^{})。在

这意味着以下代码:

cmd = ["bash", "script.sh", self.get_script_path()]
process = psutil.Popen(cmd)

time.sleep(10)  # process running here...

children = process.children(recursive=True)
for child in children:
    child.terminate()   # try to close the process "gently" first
    child.kill()

请注意,children的文档说明:

children(recursive=False)

Return the children of this process as a list of Process objects, preemptively checking whether PID has been reused.

总之,这意味着:

  1. 当您调用children时,psutil库会检查是否需要正确进程的子进程,而不是恰好具有相同pid的进程的子进程
  2. 当您调用terminatekill时,库会确保您正在杀死子进程,而不是一个具有相同pid的随机进程。在

我在ubuntu上使用命令stop process_name来停止我的进程。 希望对你有帮助。在

我认为^{}命令非常适合您。从文档页面:

Synopsis

timeout[OPTION] NUMBER[SUFFIX] COMMAND [ARG]...
timeout[OPTION]


Description

Start COMMAND, and kill it if still running after NUMBER seconds. SUFFIX may be 's' for seconds (the default), 'm' for minutes, 'h' for hours or 'd' for days.

-s, signal=SIGNAL
specify the signal to be sent on timeout.
SIGNAL may be a name like 'HUP' or a number.
        See 'kill -l' for a list of signals

通过依赖timeout,您不必担心PID重用、争用条件等复杂的细节,这些关注点被很好地封装在这个标准的Unix实用程序中。另一个好处是您的脚本将在子进程提前终止时立即恢复执行,而不是不必要地休眠整整10秒。在

bash演示:

timeout -s9 10 sleep 11; echo $?;
## Killed
## 137
timeout -s9 10 sleep 3; echo $?;
## 0

python演示:

^{pr2}$

相关问题 更多 >