在Solaris上用Python杀死进程的问题

2 投票
2 回答
2299 浏览
提问于 2025-04-16 19:16

我有一个C++程序,叫C,它的设计是当收到SIGINT信号时会关闭。我写了一个Python程序P,它会把C当作一个子进程来运行。我想让P停止C。我尝试了三种方法,但想知道为什么有些方法没有成功。

尝试 #1:

import subprocess
import signal
import os

p = subprocess.Popen(...)
...
os.killpg(p.pid, signal.SIGINT)

这段代码给了我一个错误提示:

OSError [Errno 3]: No such process`

尽管p.pidps显示的pid是匹配的。

尝试 #2:

import subprocess
import signal
import os

p = subprocess.Popen(...)
...
os.system('kill -SIGINT %u' % p.pid)

这段代码给了我一个错误提示:

sh: kill: bad signal`

尽管在终端中使用kill -SIGINT <pid>是可以正常工作的。

尝试 #3:

import subprocess
import signal
import os

p = subprocess.Popen(...)
...
os.system('kill -2 %u' % p.pid)

这个方法是成功的。

我的问题是,为什么#1和#2没有成功呢?


补充说明:我最开始的假设是,因为os.kill()的文档上说New in version 2.7: Windows support,我以为os.kill()(a)在2.7版本才有,(b) 在Windows上可以使用。看完下面的回答后,我在Solaris上运行了os.kill(),我本该一开始就这么做,抱歉,它在2.4版本上是可以工作的。显然,文档的意思是Windows支持是在2.7版本中新加的。哎呀。

2 个回答

1

Popen对象有一个叫做kill()的方法,你可以用它来结束一个进程。此外,还有一个terminate()的方法和一个通用的send_signal()方法。

我建议你使用这些方法,而不是尝试用os接口中的其他方式。因为你已经有了这个进程的控制权,应该好好利用它!

5

第一个失败是因为 os.killpg 是用来杀死一个进程“组”的,它是通过组长来识别的;而你这里只有一个简单的进程,并不是一个进程组。所以你应该试试 os.kill。第二个失败是因为 shell 自带的 kill 命令可以理解符号信号,但在 Solaris 系统上,外部命令却不支持(而在 *BSD 和 Linux 上是支持的);你可以使用数字信号(在 Solaris 上 SIGINT2,或者使用 Python 的 signal 模块中预定义的信号常量)。不过,最好还是使用 Popen 自己的接口,正如其他人提到的那样;别自己重新发明轮子,这样可能会遇到一些麻烦。

撰写回答