我想用一个程序启动多个子进程,即一个模块
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")
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()
分享我的解决方案,以防它可以帮助其他人:
我从此页面获取信息在后台运行 fortran exe。我尝试使用 os.forkpty 来获取它的 pid,但它没有给出我的进程的 pid。我无法使用子进程,因为我不知道它如何让我在后台运行我的进程。
在同事的帮助下我发现了这个:
exec_cmd = 'nohup ./FPEXE & echo $! > /tmp/pid'
os.system(exec_cmd)
如果想要将 pid 附加到同一文件,请使用双箭头。
您可以使用
os.forkpty()
来代替,它作为结果代码,为您提供伪终端的 pid 和 fd。更多文档在这里:http://docs.python.org/2/library/os.html#os.forkpty
这里我展示一个脚本,我在其中使用 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以及终端。
希望通过上面的例子可以清楚地理解这一点。