我正在创建一个定期调用外部命令的Python程序。外部命令需要一些 秒完成。我想减少外部命令终止的可能性 通过为SIGINT添加信号处理程序很糟糕。基本上,我希望SIGINT尝试等到命令 在终止Python程序之前执行。问题是外部的周长似乎是 获得SIGINT,导致它突然结束。我正在使用外部线程调用该命令,因为 根据{{3}},信号的Python文档提到只有主线程接收信号。 有人可以帮忙吗? 这是我的代码的存根。想象一下,外部程序是/ bin / sleep:
import sys
import time
import threading
import signal
def sleep():
import subprocess
global sleeping
cmd = ['/bin/sleep', '10000']
sleeping = True
p = subprocess.Popen(cmd)
p.wait()
sleeping = False
def sigint_handler(signum, frame):
if sleeping:
print 'busy, will terminate shortly'
while(sleeping): time.sleep(0.5)
sys.exit(0)
else:
print 'clean exit'
sys.exit(0)
sleeping = False
signal.signal(signal.SIGINT, sigint_handler)
while(1):
t1 = threading.Thread(target=sleep)
t1.start()
time.sleep(500)
预期的行为是在程序启动后按Ctrl + C N秒将导致 它等待(10000 - N)秒然后退出。发生的事情是程序立即终止。
谢谢!
答案 0 :(得分:3)
问题在于执行新进程时信号处理程序的修改方式。来自POSIX:
A child created via fork(2) inherits a copy of its parent's signal dis‐
positions. During an execve(2), the dispositions of handled signals
are reset to the default; the dispositions of ignored signals are left
unchanged.
所以你需要做的是:
这样,外部程序将忽略SIGINT。
当然,当脚本不响应SIGINT时,这会留下(非常)小的时间窗口。但那是你必须忍受的东西。
例如:
sleeping = False
while(1):
t1 = threading.Thread(target=sleep)
signal.signal(signal.SIGINT, signal.SIG_IGN)
t1.start()
signal.signal(signal.SIGINT, sigint_handler)
time.sleep(500)