从here中,我发现收到信号时,exit_gracefully
被调用,而while True
中的代码正在运行。起初,我认为处理程序正在另一个线程中运行,所以我编写了代码对其进行测试:
import os
import signal
import threading
def sig_handler(signal_frame, num):
print('handler PID: {}'.format(os.getpid()))
print('current thread identity: {}'.format(threading.current_thread().ident))
signal.signal(signal.SIGTERM, sig_handler)
try:
print('main execution PID: {}'.format(os.getpid()))
print('current thread identity: {}'.format(threading.current_thread().ident))
while True:
time.sleep(5)
print('Hello')
except KeyboardInterrupt:
print('Good bye')
我运行了代码,首先发送了SIGTERM
信号(使用kill -SIGTERM pid
命令),然后发送了SIGINT
信号。输出为:
main execution PID: 1002
current thread identity: 140284238558976
Hello
Hello
handler PID: 1002
current thread identity: 140284238558976
Hello
Hello
Good bye
您看到一切都一样,但是处理程序有可能在与执行主代码相同的上下文中运行吗?不应该在另一个线程中吗?
答案 0 :(得分:1)
您正在寻找的答案就在python signal documentation中:
Python信号处理程序始终在主Python线程中执行,即使在另一个线程中接收到了信号也是如此。
也:
低级信号处理程序设置一个标志,该标志告诉虚拟机在以后执行相应的Python信号处理程序
因此,当接收到信号时,处理程序不会与while
循环中的代码一起执行。相反,执行代码的虚拟机被告知运行信号处理代码“ soon”,这可能是在X字节代码指令数目之后,因此从本质上来说,在处理程序代码运行时,循环会暂停。稍微更改代码即可证明这一点:
def sig_handler(signal_frame, num):
print('handler PID: {}'.format(os.getpid()))
print('current thread identity: {}'.format(threading.current_thread().ident))
time.sleep(5) # we put a long delay here
signal.signal(signal.SIGTERM, sig_handler)
try:
print('main execution PID: {}'.format(os.getpid()))
print('current thread identity: {}'.format(threading.current_thread().ident))
while True:
time.sleep(1) # sleep less now
print('Hello')
except KeyboardInterrupt:
print('Good bye')
现在,当您发送SIGTERM时,您会注意到while循环的执行会暂停5秒。