如何从函数内定义的信号处理函数返回控制权?
How can control be returned from a signal handler function that has been defined within a function?
我正在编写一个小的单一函数,旨在请求用户输入有时间延迟。当时间延迟用完时,函数应该 return None
而不是用户的响应,然后应该继续脚本的其余部分。
在当前的实现中,用户输入有效并且超时有效,超时消息由函数内定义的信号处理函数打印(我的目标是让这个外部函数相当独立) .但是,处理随后停止(而不是退出 main
函数中定义的 while
循环),我不确定为什么。
如何让处理继续进行?我在某种程度上滥用了 signal
吗?是否可以使用 lambda 代替处理程序函数的显式定义函数?
#!/usr/bin/env python
from __future__ import print_function
import signal
import propyte
def main():
response = "yes"
while response is not None:
response = get_input_nonblocking(
prompt = "ohai? ",
timeout = 5
)
print("start non-response procedures")
# do things
def get_input_nonblocking(
prompt = "",
timeout = 5,
message_timeout = "prompt timeout"
):
def timeout_manager(signum, frame):
print(message_timeout)
#signal.signal(signal.SIGALRM, lambda: print(message_timeout))
signal.signal(signal.SIGALRM, timeout_manager)
signal.alarm(timeout)
try:
response = propyte.get_input(prompt)
return response
except:
return None
if __name__ == '__main__':
main()
你所得到的几乎就在那里,但你需要在你的信号处理程序中引发一个异常。 raw_input
将阻塞直到发生某些事情,无论是输入还是异常。如果您在信号处理程序中引发异常,那将中断 raw_input
并且执行将落入 get_input_non_blocking
函数中的 except
。这是一个玩具示例。
import signal
def timeout(signum, frame):
raise IOError("bye!")
signal.signal(signal.SIGALRM, timeout)
def input():
try:
print("omgplz: ")
return raw_input()
except IOError:
return None
signal.alarm(5)
txt = input()
signal.alarm(0)
print(txt)
这里有更多讨论和使用 select
的替代方法:Keyboard input with timeout in Python
希望对您有所帮助!
我正在编写一个小的单一函数,旨在请求用户输入有时间延迟。当时间延迟用完时,函数应该 return None
而不是用户的响应,然后应该继续脚本的其余部分。
在当前的实现中,用户输入有效并且超时有效,超时消息由函数内定义的信号处理函数打印(我的目标是让这个外部函数相当独立) .但是,处理随后停止(而不是退出 main
函数中定义的 while
循环),我不确定为什么。
如何让处理继续进行?我在某种程度上滥用了 signal
吗?是否可以使用 lambda 代替处理程序函数的显式定义函数?
#!/usr/bin/env python
from __future__ import print_function
import signal
import propyte
def main():
response = "yes"
while response is not None:
response = get_input_nonblocking(
prompt = "ohai? ",
timeout = 5
)
print("start non-response procedures")
# do things
def get_input_nonblocking(
prompt = "",
timeout = 5,
message_timeout = "prompt timeout"
):
def timeout_manager(signum, frame):
print(message_timeout)
#signal.signal(signal.SIGALRM, lambda: print(message_timeout))
signal.signal(signal.SIGALRM, timeout_manager)
signal.alarm(timeout)
try:
response = propyte.get_input(prompt)
return response
except:
return None
if __name__ == '__main__':
main()
你所得到的几乎就在那里,但你需要在你的信号处理程序中引发一个异常。 raw_input
将阻塞直到发生某些事情,无论是输入还是异常。如果您在信号处理程序中引发异常,那将中断 raw_input
并且执行将落入 get_input_non_blocking
函数中的 except
。这是一个玩具示例。
import signal
def timeout(signum, frame):
raise IOError("bye!")
signal.signal(signal.SIGALRM, timeout)
def input():
try:
print("omgplz: ")
return raw_input()
except IOError:
return None
signal.alarm(5)
txt = input()
signal.alarm(0)
print(txt)
这里有更多讨论和使用 select
的替代方法:Keyboard input with timeout in Python
希望对您有所帮助!