在 Python 程序中提供超时
Provide a timeout in Python program
我正在 python 中编写接受两个输入的程序。
一旦用户给出第一个输入,他将有 10 秒的时间进行第二个输入。
如果用户能够在这 10 秒内提供第二个值并按下回车键,则计时器停止并转到程序的下一部分。
python 中是否有任何功能允许我在 10 秒后提供中断并停止接受第二个输入。如果给出了第二个输入,则停止计时器。
您可以创建自定义 Timer class 并在不同的线程中启动它。一旦发生超时(10 秒后),您可以将 SIGINT
信号发送回父线程,这将引发我们在 main()
函数中捕获的 KeyboardInterrupt
异常。否则,您可以在用户在正确的时间输入第二个输入后停止 Timer,这将停止 Timer 线程。此外,我们可以检查 KeyboardInterrupt
是否由于超时或用户操作而发生。
注意:当我们向主进程发送信号时,我们还需要检查我们在哪个平台上 运行 程序。参见 signal.CTRL_C_EVENT and signal.SIGINT。
演示:https://repl.it/repls/StandardBuoyantProtools
解决方案:
import time
import threading
import os
import signal
class Timer(threading.Thread):
_timeout = False
_timer = 0
_stopped = False
def __init__(self, delay):
super(Timer, self).__init__()
self.restart(delay)
def is_timeout(self):
return self._timeout
def stop(self):
self._stopped = True
def restart(self, delay):
self._stopped = False
self._timer = time.time() + delay
def run(self):
while not self._stopped:
time.sleep(0.1)
if time.time() >= self._timer:
break
if not self._stopped:
self._timeout = True
# check os name
if os.name == 'nt':
# we are on Windows
os.kill(os.getpid(), signal.CTRL_C_EVENT)
else:
# we are on a Posix/Unix (or very unlikely on java) system
os.kill(os.getpid(), signal.SIGINT)
def main():
first_input = input('First input:')
delay = 10
timer = Timer(delay)
timer.daemon = True
try:
print('\nStarting the timer for the second input %r second(s)' % delay)
timer.start()
second_input = input('Second input:')
print('\nWell done. Stopping the timer!\n')
timer.stop()
print('Input values: %r %r\n' % (first_input, second_input))
# do your stuff here...
except KeyboardInterrupt:
if timer.is_timeout():
print("\nTimeout!")
else:
print("\nUser interrupted the input")
main()
我正在 python 中编写接受两个输入的程序。
一旦用户给出第一个输入,他将有 10 秒的时间进行第二个输入。 如果用户能够在这 10 秒内提供第二个值并按下回车键,则计时器停止并转到程序的下一部分。
python 中是否有任何功能允许我在 10 秒后提供中断并停止接受第二个输入。如果给出了第二个输入,则停止计时器。
您可以创建自定义 Timer class 并在不同的线程中启动它。一旦发生超时(10 秒后),您可以将 SIGINT
信号发送回父线程,这将引发我们在 main()
函数中捕获的 KeyboardInterrupt
异常。否则,您可以在用户在正确的时间输入第二个输入后停止 Timer,这将停止 Timer 线程。此外,我们可以检查 KeyboardInterrupt
是否由于超时或用户操作而发生。
注意:当我们向主进程发送信号时,我们还需要检查我们在哪个平台上 运行 程序。参见 signal.CTRL_C_EVENT and signal.SIGINT。
演示:https://repl.it/repls/StandardBuoyantProtools
解决方案:
import time
import threading
import os
import signal
class Timer(threading.Thread):
_timeout = False
_timer = 0
_stopped = False
def __init__(self, delay):
super(Timer, self).__init__()
self.restart(delay)
def is_timeout(self):
return self._timeout
def stop(self):
self._stopped = True
def restart(self, delay):
self._stopped = False
self._timer = time.time() + delay
def run(self):
while not self._stopped:
time.sleep(0.1)
if time.time() >= self._timer:
break
if not self._stopped:
self._timeout = True
# check os name
if os.name == 'nt':
# we are on Windows
os.kill(os.getpid(), signal.CTRL_C_EVENT)
else:
# we are on a Posix/Unix (or very unlikely on java) system
os.kill(os.getpid(), signal.SIGINT)
def main():
first_input = input('First input:')
delay = 10
timer = Timer(delay)
timer.daemon = True
try:
print('\nStarting the timer for the second input %r second(s)' % delay)
timer.start()
second_input = input('Second input:')
print('\nWell done. Stopping the timer!\n')
timer.stop()
print('Input values: %r %r\n' % (first_input, second_input))
# do your stuff here...
except KeyboardInterrupt:
if timer.is_timeout():
print("\nTimeout!")
else:
print("\nUser interrupted the input")
main()