jjzjj

Python 信号问题 : SIGQUIT handler delays execution if SIGQUIT received during execution of another signal handler?

coder 2023-08-19 原文

下面的程序非常简单:它每半秒输出一个点。如果它收到一个SIGQUIT,它会输出十个Q。如果它收到一个 SIGTSTP (Ctrl-Z),它会输出十个 Z

如果它在打印 Q 时收到一个 SIGTSTP,它会在完成十个 Q 后打印十个 Z s。这是好事。

但是,如果它在打印 Z 时接收到 SIGQUIT,则无法在它们之后打印 Q。相反,它仅在我通过 KeyboardInterrupt 手动终止执行后才将它们打印出来。我希望在 Z 之后立即打印 Q

这发生在使用 Python2.3 时。

我做错了什么?

#!/usr/bin/python

from signal import *
from time import sleep
from sys import stdout

def write(text):
    stdout.write(text)
    stdout.flush()

def process_quit(signum, frame):
    for i in range(10):
        write("Q")
        sleep(0.5)

def process_tstp(signum, frame):
    for i in range(10):
        write("Z")
        sleep(0.5)

signal(SIGQUIT, process_quit)
signal(SIGTSTP, process_tstp)

while 1:
    write('.')
    sleep(0.5)

最佳答案

你更大的问题是在信号处理程序中阻塞。

这通常是不鼓励的,因为它会导致奇怪的时序条件。但这并不是问题的根本原因,因为由于您选择的信号处理程序,您容易受到时序条件的影响。

无论如何,下面是如何通过仅在处理程序中设置标志并让主 while 循环执行实际工作来至少最小化计时条件的方法。代码后说明了为什么您的代码表现异常。

#!/usr/bin/python

from signal import *
from time import sleep
from sys import stdout

print_Qs = 0
print_Zs = 0

def write(text):
    stdout.write(text)
    stdout.flush()

def process_quit(signum, frame):
     global print_Qs
     print_Qs = 10

def process_tstp(signum, frame):
     global print_Zs
     print_Zs = 10

signal(SIGQUIT, process_quit)
signal(SIGTSTP, process_tstp)

while 1:
    if print_Zs:
        print_Zs -= 1
        c = 'Z'
    elif print_Qs:
        print_Qs -= 1
        c = 'Q'
    else:
        c = '.'
    write(c)
    sleep(0.5)

无论如何,这是正在发生的事情。

SIGTSTP 比 SIGQUIT 更特别。

SIGTSTP 在其信号处理程序运行时屏蔽其他信号。当内核去传递 SIGQUIT 并看到 SIGTSTP 的处理程序仍在运行时,它只是将其保存以备后用。一旦另一个信号通过传递,例如当您 CTRL+C(又名 KeyboardInterrupt)时的 SIGINT,内核会记住它从未传递过 SIGQUIT 并现在传递它。

您会注意到,如果在主循环中将 while 1: 更改为 for i in range(60): 并再次执行测试用例,程序将退出无需运行 SIGTSTP 处理程序,因为退出不会重新触发内核的信号传递机制。

祝你好运!

关于Python 信号问题 : SIGQUIT handler delays execution if SIGQUIT received during execution of another signal handler?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/109705/

有关Python 信号问题 : SIGQUIT handler delays execution if SIGQUIT received during execution of another signal handler?的更多相关文章

随机推荐