[英]Python Threading: Running 2 different functions simultaneously
I have a function foo
that only stops once a condition has been met. 我有一个函数
foo
,它只有在满足条件后才会停止。 While foo
is running, I need to ask for user input the whole time (keeps asking for user input). 当
foo
运行时,我需要一直要求用户输入(保持提示要求用户输入)。 I want them to run separately without interfering with each other. 我希望它们分开运行而不互相干扰。
In my example below, foo
keeps printing 'Hello' and getUserInput
keeps looking for user input. 在下面的示例中,
foo
继续显示“ Hello”,而getUserInput
继续查找用户输入。 I want foo to keep printing hello even if i do not enter anything for user input. 我希望foo保持打印状态,即使我没有为用户输入输入任何内容。 It will keep asking for input as long as the user does not enter letter 'e'.
只要用户不输入字母“ e”,它就会一直要求输入。 I have my attempt below:
我在下面尝试:
import threading
from time import sleep
class test:
def __init__(self):
self.running = True
def foo(self):
while(self.running):
print 'Hello\n'
sleep(2)
def getUserInput(self):
x = ''
while(x != 'e'):
x = raw_input('Enter value: ')
self.running = False
def go(self):
th1 = threading.Thread(target=self.foo)
th2 = threading.Thread(target=self.getUserInput)
th1.start()
th2.start()
t = test()
t.go()
My code prints out the first hello and asks for input but nothing after that. 我的代码打印出第一个问候,并要求输入,但此后什么也没有。 What am I doing wrong?
我究竟做错了什么? Thanks for your help in advance.
感谢您的帮助。
Update: The opener was running his code on Windows in IDLE. 更新: 开瓶器正在Windows中的IDLE中运行他的代码。 Regarding I/O it behaves differently than a shell or the Windows command line.
关于I / O,其行为与Shell或Windows命令行不同。 His code works on the Windows command line.
他的代码可在Windows命令行上使用。
In principle, your code works for me. 原则上,您的代码对我有用。 I am running Python 2.6.5.
我正在运行Python 2.6.5。
Several comments here: 这里有几条评论:
1) In your case it would be fine to only have two threads: the main thread and another one. 1)在您的情况下,最好只有两个线程:主线程和另一个线程。 However, it will also work with three.
但是,它也可以与三个一起使用。 It's just that your main thread does nothing else than waiting for the other threads to finish.
只是您的主线程除了等待其他线程完成之外没有其他操作。
2) You should to explicitly join()
all threads you spawn. 2)您应该显式
join()
生成的所有线程。 You do this in the main thread before terminating it. 您可以在终止前在主线程中执行此操作。 Keep record of the threads you spawn (eg in a list
threads
) and then join them at the end of your program (eg for t in threads: t.join()
). 记录您产生的线程(例如,在列表
threads
),然后在程序末尾将它们加入(例如, for t in threads: t.join()
)。
3) You share the variable self.running
between threads. 3)您在线程之间共享变量
self.running
。 It is fine in this case, as one thread only reads it and another one only writes it. 在这种情况下很好,因为一个线程仅读取它,而另一个仅写入它。 In general, you need to be very careful with shared variables and acquire a lock before changing it.
通常,您需要非常小心共享变量并在更改它之前获取一个锁。
4) You should catch the KeyboardInterrupt
exception in the main thread and find a way to communicate to your other threads to terminate :) 4)您应该在主线程中捕获
KeyboardInterrupt
异常,并找到一种与其他线程进行通信以终止的方法:)
5) Use lowercase method names, so instead of getUserInput
call it get_user_input
. 5)使用小写的方法名称,因此可以
get_user_input
代替getUserInput
。 Use uppercase class names and inherit from object
: class Test(object):
使用大写的类名并从
object
继承: class Test(object):
This is a running example: 这是一个正在运行的示例:
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()
When typing e or E, the program ends after a short delay (as intended by you). 键入e或E时,程序会在短暂的延迟后(根据您的预期)结束。 When pressing ctrl+c, it immediately terminates.
按ctrl + c时,它将立即终止。 Making a program that uses
threading
responsive to exceptions is a bit trickier than expected. 制作一个响应异常而使用
threading
的程序比预期的要难一些。 I have included important references in the source above. 我在上面的源代码中包含了重要的参考资料。
This is how it looks like during runtime: 这是运行时的样子:
$ python supertest.py
Hello
Enter 'e' for exit:
Hello
Hello
Hello
e
$
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.