Python Threading: Running Two Different Functions Simultaneously

I have a function foo that stops only after the condition is met. While foo working, I need to request user input all the time (continues to request user input). I want them to work separately, without interfering with each other.

In my example below, foo continues to print "Hello" and getUserInput continues to search for user input. I want foo to keep typing hi even if I didn’t enter anything for user input. It will continue to request input if the user does not enter the 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 displays the first hello and asks for input, but nothing after that. What am I doing wrong? Thank you for your help.

+4
source share
1 answer

Update: Opener ran its code on Windows in IDLE. As for I / O, this behaves differently than the shell or command prompt of Windows. Its code runs on the Windows command line.

Basically, your code works for me. I am running Python 2.6.5.

A few comments here:

1) In your case it would be nice to have only two threads: the main thread and the other. However, he will also work with three. It is just that your main thread does nothing more than wait for other threads to complete.

2) You must explicitly specify join() all the threads you create. You do this in the main thread before completing it. Save the entries that you create (for example, in the threads list), and then attach them to the end of your program (for example, for t in threads: t.join() ).

3) You split the self.running variable between threads. In this case, this is normal, since one stream only reads it, and the other writes it only. In general, you need to be very careful with shared variables and get a lock before changing it.

4) You should catch the KeyboardInterrupt exception in the main thread and find a way to communicate with your other threads:

5) Use lower case names, so instead of getUserInput call get_user_input . Use uppercase class names and inherit from object : class Test(object):

This is an 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, ie 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 you enter e or E, the program ends after a short delay (as you were told). When you press ctrl + c, it exits immediately. Creating a program that uses threading exceptions is a bit more complicated than expected. I have included important links in the source above.

Here's what it looks like at runtime:

 $ python supertest.py Hello Enter 'e' for exit: Hello Hello Hello e $ 
+6
source

Source: https://habr.com/ru/post/1433642/


All Articles