如何确定通过os.system启动的进程的pid

问题描述 投票:0回答:4

我想用一个程序启动多个子进程,即一个模块

foo.py
启动多个
bar.py
实例。

由于我有时必须手动终止进程,因此我需要进程 ID 来执行终止命令。

尽管整个设置相当“脏”,但是如果进程是通过

pid
启动的,是否有一种好的 Pythonic 方法来获取进程'
os.system

foo.py:

import os
import time
os.system("python bar.py \"{0}\ &".format(str(argument)))
time.sleep(3)
pid = ???
os.system("kill -9 {0}".format(pid))

bar.py:

import time
print("bla")
time.sleep(10) % within this time, the process should be killed
print("blubb")
python linux subprocess os.system
4个回答
17
投票

os.system
返回退出代码。它不提供子进程的 pid。

使用

subprocess
模块。

import subprocess
import time
argument = '...'
proc = subprocess.Popen(['python', 'bar.py', argument], shell=True)
time.sleep(3) # <-- There's no time.wait, but time.sleep.
pid = proc.pid # <--- access `pid` attribute to get the pid of the child process.

要终止进程,可以使用

terminate
方法或
kill
。 (无需使用外部
kill
程序)

proc.terminate()

4
投票

分享我的解决方案,以防它可以帮助其他人:

我从此页面获取信息在后台运行 fortran exe。我尝试使用 os.forkpty 来获取它的 pid,但它没有给出我的进程的 pid。我无法使用子进程,因为我不知道它如何让我在后台运行我的进程。

在同事的帮助下我发现了这个:

exec_cmd = 'nohup ./FPEXE & echo $! > /tmp/pid'

os.system(exec_cmd)

如果想要将 pid 附加到同一文件,请使用双箭头。


3
投票

您可以使用

os.forkpty()
来代替,它作为结果代码,为您提供伪终端的 pid 和 fd。更多文档在这里:http://docs.python.org/2/library/os.html#os.forkpty


0
投票

这里我展示一个脚本,我在其中使用 gnome 终端运行脚本,然后终止 scbscript 终端。

import os
import subprocess
import signal
import time
import psutil

def kill_process_tree(pid, sig=signal.SIGTERM):
    try:
        parent = psutil.Process(pid)
        for child in parent.children(recursive=True):
            child.kill()
        parent.kill()
    except psutil.NoSuchProcess:
        pass

script_name = 'my_program.py'
command = ["gnome-terminal", "--", "python3", script_name]

# Start the gnome-terminal with the script using subprocess.Popen
process = subprocess.Popen(command)
print(f"Running gnome-terminal process: {process.pid}")

# Wait for a few seconds to let the process start
time.sleep(5)

# Find the PIDs of the script running in the terminal
try:
    script_pids = subprocess.check_output(["pgrep", "-f", script_name]).strip().split()
script_pids = [int(pid) for pid in script_pids]
    print(f"Script PIDs: {script_pids}")
except subprocess.CalledProcessError:
    print(f"Could not find PID for the script {script_name}")
    script_pids = []

# Kill the gnome-terminal process
print(f"Killing gnome-terminal process, pid: {process.pid}")
kill_process_tree(process.pid)

# If script PIDs were found, kill the script processes
for script_pid in script_pids:
    print(f"Killing script process, pid: {script_pid}")
    kill_process_tree(script_pid)

在 GNOME 终端中,终端将启动另一个进程,即脚本,并且简单地终止终端进程可能不会终止其中运行的脚本。所以我们需要获取脚本本身的进程ID以及终端。

希望通过上面的例子可以清楚地理解这一点。

© www.soinside.com 2019 - 2024. All rights reserved.