我有一个python script.py
,它启动子进程并在循环中完成一些工作。这个程序大部分时间在发送SIGUSR2时正确退出,在一些罕见的情况下,我不明白它不会。
这是最小的工作示例
import os, subprocess,signal,sys,time
sub = None
shutDown = False
def handler(signum,frame):
global shutDown, sub
print("script.py: cached sig: %i " % signum)
sys.stdout.flush()
if shutDown:
print("ignoring signal: %i " % signum)
return
else:
shutDown = True
if sub is not None and not sub.poll():
print("script.py: sent signal to doStuff.sh pid: ", sub.pid)
sys.stdout.flush()
os.kill(sub.pid, signal.SIGTERM)
os.waitpid(sub.pid,0)
sys.exit(128+signum)
signal.signal(signal.SIGINT, handler)
signal.signal(signal.SIGUSR2, handler)
signal.signal(signal.SIGTERM, handler)
for i in range(0,5):
print("launching %i" % i)
sub = subprocess.Popen(["./doStuff.sh"], stderr = subprocess.STDOUT)
sub.wait()
print("finished script.py")
使用doStuff
存根
function signalHandler() {
trap '' SIGINT
trap '' SIGTERM
sleep 10s
# kill ourself to signal calling process we exited on SIGINT
trap - SIGINT
kill -s SIGINT $$
}
trap_with_arg "signalHandler" SIGINT SIGTERM
trap '' SIGUSR2
echo "doStuff.sh : pid: $$"
for i in {1..100}; do
sleep 1s
done
现在启动python script.py
并发送两次SIGINT
(kill -INT -thePID
或按两次Ctrl+C
,其中一秒钟:
launching 0
doStuff.sh : pid: 7720
^Cscript.py: cached sig: 2 /** < first time CTRL + C
script.py: sent signal to doStuff.sh pid: 7720 /** < doStuff is waiting now
^Cscript.py: cached sig: 2 /** < second time CTRL + C
ignoring signal: 2
launching 1 /** < why continuing loop??? so python
...
我真的想知道为什么循环继续,因为在处理程序的末尾有一个sys.exit
我希望第一次调用shutDownHandler
最终应该调用sys.exit
。
有人看到这个程序有什么缺陷吗?真的很难让它发挥作用。