gpt4 book ai didi

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

转载 作者:太空狗 更新时间:2023-10-29 20:24:52 25 4
gpt4 key购买 nike

下面的程序非常简单:它每半秒输出一个点。如果它收到一个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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com