Python input and output threading - python

I want to create a python script that prints out messages from one thread, while still waiting for you to input on another. Is this possible? And if so, how?
System: Windows 7
Language: Python 2.7
I have tried this (modified from a different question):
import threading
import time
def message_loop():
while True:
time.sleep(1)
print "Hello World"
thread = threading.Thread(target = message_loop)
thread.start()
while True:
input = raw_input("Prompt> ")
But what happens is: the program waits until I have finished inputting before it outputs Hello World.

It's absolutely possible. If you have a function that prints output (let's call it print_output) you can start it up in a different thread using the threading module:
>>> import threading
>>> my_thread = threading.Thread(target=print_output)
>>> my_thread.start()
You should now start getting your output. You can then run the input bit on the main thread. You could also run it in a new thread, but there are some advantages to running input in the main thread.

This works for me.
The code prints message before you input 'q'
import threading
import time
def run_thread():
while True:
print('thread running')
time.sleep(2)
global stop_threads
if stop_threads:
break
stop_threads = False
t1 = threading.Thread(target=run_thread)
t1.start()
time.sleep(0.5)
q = ''
while q != 'q':
q = input()
stop_threads = True
t1.join()
print('finish')

Related

How to run a side task while also waiting for getch?

So I have this small program (using Linux):
import getch
while True:
print("Hello World!")
key = getch.getch()
if key == 'q':
break
So all it does is wait for the user to hit a key, and they displays "Hello World!" to the console. However, is there a way so that I can continuously display "Hello World!" to the console, and the only way to get it to end is if the user presses the "q" key?
This question is similar to this one, but it's in C++.
My first thought was to look up threading, however, I tried all the threads I could find and none of them worked. Then I came across the Global Interpreter Lock (GIL), and it supposedly prevents "multiple native threads from executing Python bytecodes at once."
Then I tried to use multiprocessing, but it still didn't work for me. This is how far I got using it:
import multiprocessing
import getch
def test1():
print("Hello World!")
def test2():
key = getch.getch()
if key == 'q':
exit()
while True:
p1 = multiprocessing.Process(target=test1, args=())
p2 = multiprocessing.Process(target=test2, args=())
p1.start()
p2.start()
p1.join()
p2.join()
Am I missing something here? Or is there another way in which I can do something while also waiting for getch()? Or do I have to write this in another language that supports multithreading like C++?
Thanks
I was not able to install fetch, probably because I am on Windows at the moment, but you can implement what you want (However, is there a way so that I can continuously display "Hello World!" to the console, and the only way to get it to end is if the user presses the "q" key?) the following way:
import time
from threading import Thread
def another_thread():
while True:
time.sleep(2)
print("Working...\n")
def main_thread():
while True:
x = input("Press a key: \n")
if x == "q":
break
if __name__ == '__main__':
# create another Thread object
# daemon means that it will stop if the Main Thread stops
th = Thread(target=another_thread, daemon=True)
th.start() # start the side Thread
main_thread() # start main logic

How can I make the print() function not take the text in the input field with it

I am trying to make a console for my python applications, but i ran into a problem:
when printing something using the print() function, the text in the input field is also included. This is purely visual, because the program still works.
I tried searching online, but I do not even now what to search for and had no luck.
This is my code. It prints "foo" until the user types "exit":
import multiprocessing as mp
import os
import time
def f(q):
while True:
print(q)
time.sleep(1)
if __name__=="__main__":
p=mp.Process(target=f, args=("foo",))
p.start()
while True:
comm=str(input())
if comm=="exit":
p.terminate()
break
When the program is running, the user can still type, but when the program prints something, it also takes whatever is in the input field at the time:
foo
foo
foo
foo
efoo
xfoo
itfoo
When pressing "enter", the program still registers the input correctly and exits the program.
Here is a modification of your code that only prints foo after you have finished your input typing (i.e., until you hit Enter):
import multiprocessing as mp
from multiprocessing import Queue
def f(q, queue):
while True:
queue.get()
print(q)
if __name__=="__main__":
queue = Queue()
p=mp.Process(target=f, args=("foo", queue))
p.start()
while True:
comm=str(input())
queue.put(None)
if comm=="exit":
p.terminate()
break
If terminating the process is all you want your user to be able to do, then you can instruct them to enter Ctrl+C if they wish to stop the operation and then catch the KeyboardInterrupt exception that comes along with it.
import multiprocessing as mp
import os
import time
def f(q):
while True:
print(q)
time.sleep(1)
if __name__=="__main__":
p=mp.Process(target=f, args=("foo",))
print("Process starting. Use Ctrl+c anytime to stop it!")
p.start()
try:
while True:
input() # Trash command
except KeyboardInterrupt:
print("Terminating process...")
p.terminate()
print("Process terminated...")
If you want to do more complicated commands then a GUI would be your best approach (as mentioned by John)

Python input() call blocks other threads from printing to console

Thread1: Just blocks on user-input, and then adds the input to a queue before going back to blocking.
Thread2: Prints to console.
I don't see Thread2 outputs unless I enter something on the console. i.e unblock thread1. Is there a way to output to console while also blocking on input in another thread?
import threading
import time
def reader():
while(1):
text=input()
def writer():
while(1):
time.sleep(1)
print("Thread 2")
t1 = threading.Thread(target=reader)
t2 = threading.Thread(target=writer)
t1.start()
t2.start()
while(1):
#Do nothing
time.sleep(1)
Environment: Windows, WPy 3.6.7

Get live value of variable from another script

I have two scripts, new.py and test.py.
Test.py
import time
while True:
x = "hello"
time.sleep(1)
x = "world"
time.sleep(1)
new.py
import time
while True:
import test
x = test.x
print(x)
time.sleep(1)
Now from my understanding this should print "hello" and a second later "world" all the time when executing new.py.
It does not print anything, how can i fix that?
Thanks
I think the code below captures what you are asking. Here I simulate two scripts running independently (by using threads), then show how you can use shelve to communicate between them. Note, there are likely much better ways to get to what you are after -- but if you absolutely must run the scripts independently, this will work for you.
Incidentally, any persistent source would do (such as a database).
import shelve
import time
import threading
def script1():
while True:
with shelve.open('my_store') as holder3:
if holder3['flag'] is not None: break
print('waiting')
time.sleep(1)
print("Done")
def script2():
print("writing")
with shelve.open('my_store') as holder2:
holder2['flag'] = 1
if __name__ == "__main__":
with shelve.open('my_store') as holder1:
holder1['flag'] = None
t = threading.Thread(target=script1)
t.start()
time.sleep(5)
script2()
t.join()
Yields:
waiting
waiting
waiting
waiting
waiting
writing
Done
Test.py
import time
def hello():
callList = ['hello', 'world']
for item in callList:
print item
time.sleep(1)
hello()
new.py
from parent import hello
while True:
hello()

unable to create a thread in python

I have following code which compares user input
import thread,sys
if(username.get_text() == 'xyz' and password.get_text()== '123' ):
thread.start_new_thread(run,())
def run():
print "running client"
start = datetime.now().second
while True:
try:
host ='localhost'
port = 5010
time = abs(datetime.now().second-start)
time = str(time)
print time
client = socket.socket()
client.connect((host,port))
client.send(time)
except socket.error:
pass
If I just call the function run() it works but when I try to create a thread to run this function, for some reason the thread is not created and run() function is not executed I am unable to find any error..
Thanks in advance...
you really should use the threading module instead of thread.
what else are you doing? if you create a thread like this, then the interpreter will exit no matter if the thread is still running or not
for example:
import thread
import time
def run():
time.sleep(2)
print('ok')
thread.start_new_thread(run, ())
--> this produces:
Unhandled exception in thread started by
sys.excepthook is missing
lost sys.stderr
where as:
import threading
import time
def run():
time.sleep(2)
print('ok')
t=threading.Thread(target=run)
t.daemon = True # set thread to daemon ('ok' won't be printed in this case)
t.start()
works as expected. if you don't want to keep the interpreter waiting for the thread, just set daemon=True* on the generated Thread.
*edit: added that in example
thread is a low level library, you should use threading.
from threading import Thread
t = Thread(target=run, args=())
t.start()

Categories