I have a function foo that only stops once a condition has been met. While foo is running, I need to ask for user input the whole time (keeps asking for user input). 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. I want foo to keep printing hello even if i do not enter anything for user input. It will keep asking for input as long as the user does not enter letter ‘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. Regarding I/O it behaves differently than a shell or the Windows command line. His code works on the Windows command line.
In principle, your code works for me. I am running 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. 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. You do this in the main thread before terminating it. Keep record of the threads you spawn (e.g. in a listthreads) and then join them at the end of your program (e.g.for t in threads: t.join()).3) You share the variable
self.runningbetween threads. 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
KeyboardInterruptexception in the main thread and find a way to communicate to your other threads to terminate 🙂5) Use lowercase method names, so instead of
getUserInputcall itget_user_input. Use uppercase class names and inherit fromobject:class Test(object):This is a running example:
When typing e or E, the program ends after a short delay (as intended by you). When pressing ctrl+c, it immediately terminates. Making a program that uses
threadingresponsive to exceptions is a bit trickier than expected. I have included important references in the source above.This is how it looks like during runtime: