python

时间:2018-10-06 09:27:43

标签: python signals

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

您看到一切都一样,但是处理程序有可能在与执行主代码相同的上下文中运行吗?不应该在另一个线程中吗?

1 个答案:

答案 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秒。