首先,我不确定您是否需要第二个线程来设置shutdown_flag
。
为什么不直接在SIGTERM处理程序中设置它?
一种替代方法是从SIGTERM
处理程序引发异常,该异常将在堆栈中传播。假设您已经进行了适当的异常处理(例如,使用with
/ contextmanager
和try: ... finally:
块),这应该是一个相当正常的关闭过程,类似于Ctrl+C您的程序。
示例程序signals-test.py
:
#!/usr/bin/python
from time import sleep
import signal
import sys
def sigterm_handler(_signo, _stack_frame):
# Raises SystemExit(0):
sys.exit(0)
if sys.argv[1] == "handle_signal":
signal.signal(signal.SIGTERM, sigterm_handler)
try:
print "Hello"
i = 0
while True:
i += 1
print "Iteration #%i" % i
sleep(1)
finally:
print "Goodbye"
现在查看Ctrl+C行为:
$ ./signals-test.py default
Hello
Iteration #1
Iteration #2
Iteration #3
Iteration #4
^CGoodbye
Traceback (most recent call last):
File "./signals-test.py", line 21, in <module>
sleep(1)
KeyboardInterrupt
$ echo $?
1
这次,我SIGTERM
经过4次迭代后将其发送给kill $(ps aux | grep signals-test | awk '/python/ {print $2}')
:
$ ./signals-test.py default
Hello
Iteration #1
Iteration #2
Iteration #3
Iteration #4
Terminated
$ echo $?
143
这次,我启用了自定义SIGTERM
处理程序并将其发送SIGTERM
:
$ ./signals-test.py handle_signal
Hello
Iteration #1
Iteration #2
Iteration #3
Iteration #4
Goodbye
$ echo $?
0
signalfd
和屏蔽SIGTERM
流程的交付来满足您的要求。