Python 获取子进程的pid

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3332043/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 10:29:36  来源:igfitidea点击:

obtaining pid of child process

pythondjangopython-multiprocessing

提问by tazim

I am using python's multiprocessing module to spawn new process

我正在使用 python 的多处理模块来生成新进程

as follows :

如下 :

import multiprocessing
import os
d = multiprocessing.Process(target=os.system,args=('iostat 2 > a.txt',))
d.start()

I want to obtain pid of iostat command or the command executed using multiprocessing module

我想获取 iostat 命令的 pid 或使用多处理模块执行的命令

When I execute :

当我执行:

 d.pid 

it gives me pid of subshell in which this command is running .

它给了我运行这个命令的子shell的pid。

Any help will be valuable .

任何帮助都是有价值的。

Thanks in advance

提前致谢

回答by whaley

I think with the multiprocess module you might be out of luck since you are really forking python directly and are given that Process object instead of the process you are interested in at the bottom of the process tree.

我认为使用 multiprocess 模块你可能不走运,因为你真的直接 fork python 并且在进程树的底部给出了 Process 对象而不是你感兴趣的进程。

An alternative way, but perhaps not optimal way, to get that pid is to use the psutilmodule to look it up using the pid obtained from your Process object. Psutil, however, is system dependent and will need to be installed separately on each of your target platforms.

获取该 pid 的另一种方法(但可能不是最佳方法)是使用psutil模块使用从 Process 对象获得的 pid 来查找它。但是,Psutil 依赖于系统,需要在每个目标平台上单独安装。

Note: I'm not currently at a machine I typically work from, so I can't provide working code nor play around to find a better option, but will edit this answer when I can to show how you might be able to do this.

注意:我目前不在我通常使用的机器上,因此我无法提供工作代码,也无法四处寻找更好的选择,但是我会在可以时编辑此答案以展示您如何能够做到这一点.

回答by Ilia Barahovski

For your example you may use the subprocesspackage. By default it executes the command without shell (like os.system()) and provides a PID:

对于您的示例,您可以使用该subprocess包。默认情况下,它在没有 shell 的情况下执行命令(如os.system())并提供一个 PID:

from subprocess import Popen
p = Popen('iostat 2 > a.txt', shell=True)
processId = p.pid
p.communicate() # to wait until the end

The Popenalso provides ability to connect to standard input and output of the process.

Popen还提供了连接到标准输入和过程输出的能力。

note: before using shell=Truebe aware of the security considerations.

注意:使用前shell=True要了解的安全注意事项

回答by rakslice

Since you appear to be using Unix, you can use a quick pscommand to get the details of the child processes, like I did here (this is Linux-specific):

由于您似乎在使用 Unix,您可以使用快速ps命令来获取子进程的详细信息,就像我在这里所做的一样(这是 Linux 特定的):

import subprocess, os, signal

def kill_child_processes(parent_pid, sig=signal.SIGTERM):
        ps_command = subprocess.Popen("ps -o pid --ppid %d --noheaders" % parent_pid, shell=True, stdout=subprocess.PIPE)
        ps_output = ps_command.stdout.read()
        retcode = ps_command.wait()
        assert retcode == 0, "ps command returned %d" % retcode
        for pid_str in ps_output.split("\n")[:-1]:
                os.kill(int(pid_str), sig)

回答by zhanxw

Similar to @rakslice, you can use psutil:

与@rakslice 类似,您可以使用psutil

import signal, psutil
def kill_child_processes(parent_pid, sig=signal.SIGTERM):
    try:
      parent = psutil.Process(parent_pid)
    except psutil.NoSuchProcess:
      return
    children = parent.children(recursive=True)
    for process in children:
      process.send_signal(sig)

回答by Ankur Agarwal

[me@localhost ~]$ echo $$
30399
[me@localhost ~]$ cat iostat.py 
#!/usr/bin/env python3.4 

import multiprocessing
import os
d = multiprocessing.Process(target=os.system,args=('iostat 2 > a.txt',))
d.start()

[me@localhost ~]$ ./iostat.py &
[1] 31068
[me@localhost ~]$ watch -n 3 'pstree -p 30399'
[me@localhost ~]$ 

This gave me the PID of iostatSee image. process tree

这给了我iostat查看图像的PID 。进程树