更新: 开启者在空闲的 Windows 上运行他的代码。关于 I/O,它的行为不同于 shell 或 Windows 命令行。他的代码适用于 Windows 命令行。
原则上,您的代码对我有用。我正在运行 Python 2.6.5。
这里有几条评论:
1)在您的情况下,只有两个线程就可以了:主线程和另一个线程。但是,它也适用于三个。只是您的主线程除了等待其他线程完成之外什么都不做。
2)你应该明确join()
你产生的所有线程。在终止它之前在主线程中执行此操作。记录您产生的线程(例如在列表中threads
),然后在程序结束时加入它们(例如for t in threads: t.join()
)。
self.running
3)您在线程之间共享变量。在这种情况下很好,因为一个线程只读取它而另一个线程只写入它。通常,您需要非常小心共享变量并在更改之前获取锁。
4)您应该在主线程中捕获KeyboardInterrupt
异常并找到一种与其他线程通信以终止的方法:)
5) 使用小写的方法名,所以不要getUserInput
调用它get_user_input
。使用大写的类名并继承自object
:class Test(object):
这是一个运行示例:
import threading
from time import sleep
def main():
t = Test()
t.go()
try:
join_threads(t.threads)
except KeyboardInterrupt:
print "\nKeyboardInterrupt catched."
print "Terminate main thread."
print "If only daemonic threads are left, terminate whole program."
class Test(object):
def __init__(self):
self.running = True
self.threads = []
def foo(self):
while(self.running):
print '\nHello\n'
sleep(2)
def get_user_input(self):
while True:
x = raw_input("Enter 'e' for exit: ")
if x.lower() == 'e':
self.running = False
break
def go(self):
t1 = threading.Thread(target=self.foo)
t2 = threading.Thread(target=self.get_user_input)
# Make threads daemonic, i.e. terminate them when main thread
# terminates. From: http://stackoverflow.com/a/3788243/145400
t1.daemon = True
t2.daemon = True
t1.start()
t2.start()
self.threads.append(t1)
self.threads.append(t2)
def join_threads(threads):
"""
Join threads in interruptable fashion.
From http://stackoverflow.com/a/9790882/145400
"""
for t in threads:
while t.isAlive():
t.join(5)
if __name__ == "__main__":
main()
键入 e 或 E 时,程序会在短暂延迟后结束(如您所愿)。当按下 ctrl+c 时,它立即终止。制作一个使用threading
响应异常的程序比预期的要复杂一些。我在上面的来源中包含了重要的参考资料。
这是它在运行时的样子:
$ python supertest.py
Hello
Enter 'e' for exit:
Hello
Hello
Hello
e
$