Python - 直到按键或超时才做某事

Ben*_*son 9 python multithreading timeout keypress wait

我几乎已经解决了这个问题,但我认为我需要朝着正确的方向努力.

我想要做的事每五秒钟,直到或者一定的时间量已过去用户中断它(在这种情况下,完成循环的该迭代完成之前).

import time
import threading

def do_something():
    T0 = time.clock()
    while (time.clock() - T0) < 60 and not e.isSet(): #as long as 60s haven't elapsed
                                                      #and the flag is not set
        #here do a bunch of stuff
        time.sleep(5)

thread = threading.Thread(target=do_something, args=())
thread.start()
e = threading.Event()

while thread.isAlive():
    #here I want the main thread to wait for a keypress and, if it receives it,
    #set the event e, which will cause the thread to finish its work.
Run Code Online (Sandbox Code Playgroud)

我无法弄清楚如何使最后一行工作.raw_input()在循环内部使用将阻塞,直到用户命中输入线程是否完成其工作.还有另一个模块可以做我想要的吗?

编辑:我正在使用Windows XP.

Ben*_*son 2

这是我解决问题的方法。我真的不想转移到较低级别的thread模块,并且我决定我很高兴用户使用 CTRL-C 使程序正常退出。

由于它重新调整用途的方式,这有点麻烦KeyboardInterrupt,这意味着它不能真正嵌入到需要CTRL-C 来作为不优雅退出的代码中。不过对于我的目的来说这是可以的。

import time
import threading

def do_something():
    T0 = time.clock()
    while (time.clock() - T0) < 60 and not e.isSet(): #as long as 60s haven't elapsed
                                                      #and the flag is not set
        #here do a bunch of stuff
        time.sleep(5)

thread = threading.Thread(target=do_something, args=())
e = threading.Event()
thread.start()

print 'Press CTRL-C to interrupt'
while thread.isAlive():
    try: time.sleep(1) #wait 1 second, then go back and ask if thread is still alive
    except KeyboardInterrupt: #if ctrl-C is pressed within that second,
                              #catch the KeyboardInterrupt exception
        e.set() #set the flag that will kill the thread when it has finished
        print 'Exiting...'
        thread.join() #wait for the thread to finish
Run Code Online (Sandbox Code Playgroud)

更新:实际上,使用 GUI 按钮要简单得多。下面的代码不涉及稍微不完整的重新调整用途KeyboardInterrupt

import time
import threading
import Tkinter as Tk

def do_something():
    T0 = time.clock()
    while (time.clock() - T0) < 60 and not e.isSet(): #as long as 60s haven't elapsed
                                                      #and the flag is not set
        #here do a bunch of stuff
        time.sleep(5)

def _quit():
    print 'Exiting...'
    e.set()
    thread.join() #wait for the thread to finish
    root.quit()
    root.destroy()

root = Tk.Tk()
QuitButton = Tk.Button(master=root, text='Quit', command=_quit) #the quit button
QuitButton.pack(side=Tk.BOTTOM)

thread = threading.Thread(target=do_something, args=())
e = threading.Event()
thread.start()
root.mainloop()
Run Code Online (Sandbox Code Playgroud)