在Python中启动进程并重用PID

1 投票
1 回答
661 浏览
提问于 2025-04-18 07:15

我的主程序/线程启动了一个可执行文件,这个文件在输出 Algorithm loaded 后开始等待一个信号。我使用的是 subprocess.Popen 类来运行这个可执行文件。

后来,我又启动了一个线程,这个线程是用来给之前启动的可执行文件发送信号的。但是我不知道怎么从这个线程给那个特定的子进程发送信号。

我想知道是否可以通过 PID(进程ID)来“恢复”子进程?我想重用这个进程,目的是发送一些类似于 stdin 的内容。

以下是我启动可执行文件的代码:

def start_module():
    cmd = '%s/libraries/OpenBR' % settings.MODULES_DIR
    process = subprocess.Popen(cmd,stdout=subprocess.PIPE)

    while True:
        line = process.stdout.readline()
        if line.find('Algorithm loaded') > -1:
            break

    return 0

1 个回答

4

你代码里的 process 变量指的是一个 Popen 对象,这个对象有一个叫 pid 的属性。如果你让 start_module 函数返回这个进程,之后你就可以用 os.kill 给它发送信号。例如:

def start_module():
    cmd = '%s/libraries/OpenBR' % settings.MODULES_DIR
    process = subprocess.Popen(cmd,stdout=subprocess.PIPE)

    while True:
        line = process.stdout.readline()
        if line.find('Algorithm loaded') > -1:
            break

    return process

p = start_module()
os.kill(p.pid, signal.SIGALRM)

根据我的观察,使用线程来发送信号和不使用线程是没有区别的。需要注意的是,os.kill 并不一定会杀掉一个进程:它只是发送一个信号,进程可以根据这个信号做出相应的处理(这里是 ALARM 信号)。


如果你想给进程的 stdin 输入一些内容,那也很简单。你只需要在调用 Popen 时加上 stdin=subprocess.PIPE,然后就可以向新进程的 stdin 属性打印内容:

def start_module():
    cmd = '%s/libraries/OpenBR' % settings.MODULES_DIR
    process = subprocess.Popen(cmd,stdin=subprocess.PIPE,stdout=subprocess.PIPE)

    while True:
        line = process.stdout.readline()
        if line.find('Algorithm loaded') > -1:
            break

    return process

p = start_module()
print >> p.stdin, "Hello world!"
print >> p.stdin, "How are things there?"

撰写回答