在 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()