我正在使用python来管理一些模拟。我使用以下命令构建参数并运行程序:
pipe = open('/dev/null', 'w')
pid = subprocess.Popen(shlex.split(command), stdout=pipe, stderr=pipe)
我的代码处理不同的信号。Ctrl+C将停止模拟,询问我是否要保存,然后优雅地退出。我还有其他的信号处理程序(比如强制数据输出)。
我想要的是向我的python脚本发送一个信号(SIGINT,Ctrl+C),它将询问用户他想要向程序发送哪个信号。
唯一阻止代码工作的事情似乎是,无论我做什么,Ctrl+C都将被“转发”到子进程:代码将捕获它并退出:
try:
<wait for available slots>
except KeyboardInterrupt:
print "KeyboardInterrupt catched! All simulations are paused. Please choose the signal to send:"
print " 0: SIGCONT (Continue simulation)"
print " 1: SIGINT (Exit and save)"
[...]
answer = raw_input()
pid.send_signal(signal.SIGCONT)
if (answer == "0"):
print " --> Continuing simulation..."
elif (answer == "1"):
print " --> Exit and save."
pid.send_signal(signal.SIGINT)
[...]
因此,无论我做什么,程序都会接收到我只想让我的python脚本看到的SIGINT。我该怎么做?
我也试过了:
signal.signal(signal.SIGINT, signal.SIG_IGN)
pid = subprocess.Popen(shlex.split(command), stdout=pipe, stderr=pipe)
signal.signal(signal.SIGINT, signal.SIG_DFL)
来运行程序,但这会产生相同的结果:程序捕获SIGINT。
谢谢!
发布于 2011-02-03 03:18:39
我通过创建一个我调用的助手应用程序而不是直接创建子应用程序解决了这个问题。这个帮助器更改它的父组,然后产生真正的子进程。
import os
import sys
from time import sleep
from subprocess import Popen
POLL_INTERVAL=2
# dettach from parent group (no more inherited signals!)
os.setpgrp()
app = Popen(sys.argv[1:])
while app.poll() is None:
sleep(POLL_INTERVAL)
exit(app.returncode)
我在父对象中调用这个helper,将真正的子对象及其参数作为参数传递:
Popen(["helper", "child", "arg1", ...])
我必须这样做,因为我的孩子应用程序不在我的控制之下,如果它在我的控制之下,我可以在那里添加setpgrp并完全绕过帮助程序。
https://stackoverflow.com/questions/3791398
复制相似问题