i have a thread running on the background checking every 5 sec and print a msg after 5 secs passes.
in loop1 the msg should appear at specific point. (in this case, its above print('test')).
the thread can wait longer than 5 secs when loop1 is running (like a few sec delay is fine) but it have not to appear at the same time as loop1 is running so i put queue to for blocking.
when loop2 is running, the messsage in the multithread should appear while loop2 is running at the same time unlike loop no1.
so i didnt put queue.get in loop2 since theres no need for blocking but the problem is when going into loop3. if we go into loop3 while we are on time.sleep(5) in multithread, thats fine but if we are on print ("thread working2") in multithread, i want to make sure it waits until it does all the work in print ("thread working2") part. there are more codes there but i just put a simple print for better readability. before going into loop3. is there any way i can accomplish this? and is the method im using right now is suitable for my intention?
sorry for my bad english!
import threading
import time
from queue import Queue
queue = Queue()
queue2 = Queue()
switch = False
def func0():
while True:
global switch
global queue
global queue2
time.sleep(5)
switch = True
print ("switch on")
a = queue.get()
if a == 1:
print("thread working")
time.sleep(0.5)
print("thread working")
time.sleep(0.5)
switch = False
queue2.put(True)
if a == 2:
print("thread working2")
time.sleep(0.5)
print("thread working2")
time.sleep(0.5)
switch = False
if __name__ == "__main__":
t1 = threading.Thread(target=func0)
t1.start()
testnumber = 0
testnumber2 = 0
testnumber3 = 0
while True: #loop no.1
if switch:
queue.put(1)
queue2.get()
print ("loop1")
time.sleep(0.5)
testnumber = testnumber +1
if testnumber == 200:
break
while True: #loop no.2
if switch:
queue.put(2)
print ("loop2")
time.sleep(0.5)
testnumber2 = testnumber2 + 1
if testnumber2 == 200:
break
while True: #loop no.3
print ("loop3")
time.sleep(0.5)
testnumber3 = testnumber3 + 1
if testnumber3 == 200:
break
t1.join()
Related
I'm looking to terminate a thread after a certain amount of time. The thread is called from an infinite while loop that waits for users input. Thread starts after user inputs number 4 from command line, after which thread writes some text to the console in another infinite loop. After x amount of time the started thread should terminate. How can I make the thread stop after the set time while keeping the main thread with user input responsive (active)?
Here is some sample code:
def loop():
while True:
print("ON")
print("OFF")
if __name__ == "__main__":
t = threading.Thread(target=loop)
try:
while True:
print(">>", end='')
command = int(input())
if command == 1:
...
elif command == 2:
...
elif command == 3:
...
elif command == 4:
print("Insert time:")
time = float(input())
t.start()
elif command == 5:
...
It is possible to pass an argument to the loop and that can be used to stop the thread, something like this:
def loop(running):
while running[0]:
print("HELLO")
if __name__ == "__main__":
running = [True]
t = threading.Thread(target=loop, args=(running,))
t.start()
while True:
command = input()
running[0] = False
running is shared by both the main thread and the other thread, so changing the value in one changes it in the other.
I checked threads and solutions about multiprocessing on pyhton 3, but could not adapt it to my case because its containing a loop:
import time
anotherFunctionRunning = False
def anotherFunction():
global anotherFunctionRunning
anotherFunctionRunning = True
print("Another function started")
time.sleep(5)
print("Another function stopped running")
anotherFunctionRunning = False
def mainLoop():
global anotherFunctionRunning
while True:
print("running")
time.sleep(1)
if (anotherFunctionRunning == False):
anotherFunction()
else:
print("loop running, another function running")
print("loop ended")
mainLoop()
My problem here is when anotherFunction starts running, script waits it to be over (in the example 5 seconds) and continues the loop.
I want it to continue the loop while anotherFunction running.
I saw this common solution but could not adapt it to my case and dont know how to do because its becoming too complex:
from multiprocessing import Process
def func1:
#does something
def func2:
#does something
if __name__=='__main__':
p1 = Process(target = func1)
p1.start()
p2 = Process(target = func2)
p2.start()
Any ideas ?
Thanks for support
I'm not sure I understand what you want, but I think this should do the job
import time
from threading import Thread
anotherFunctionRunning = False
def anotherFunction():
global anotherFunctionRunning
anotherFunctionRunning = True
print("Another function started")
time.sleep(5)
print("Another function stopped running")
anotherFunctionRunning = False
def mainLoop():
global anotherFunctionRunning
thread = None
counter = 0
while counter < 5:
counter += 1
print("running")
time.sleep(1)
if anotherFunctionRunning == False:
thread = Thread(target= anotherFunction, name="AnotherThread")
thread.start()
else:
print("loop running, another function running")
print("loop ended")
thread.join()
mainLoop()
Beware however I have royally ignored the dangers of competitive access
I have made a thread that is supposed to show the seconds passing. Unfortunately, when I use getstr from the curses module the whole script stops, including the thread. I have to use a thread lock to stop random characters being printed out because of overlapping orders.
Any suggestions on how to fix this or an alternative would be great!
In the below example window and window2 are already set-up...
lock = threaing.Lock()
def main_function():
#starts thread
t1 = threading.Thread(target=time_calc,args=(window2,))
t1.start()
#Gets user input
while True:
data = window1.addstr(y,x,"Type something in!")
data = window1.getstr(y,x,5)
lock.acquire()
window1.erase()
txt = "You said: "+data
window1.addstr(y,x,txt)
lock.release()
def time_calc(window2):
current_count = 0
while True:
time += 1
text = "Time Count: "+str(time)
lock.acquire()
window2.erase()
window2.addstr(y,x,text)
lock.release()
time.sleep(1)
The problem with my code
I figured out the problem with my code. You can't run a thread inside a thread for some reason and I originally had my main function called to be considered a thread. I guess I should have stated this in my question. Sorry
There is probably a way to run a thread in a thread, but this did not work for me.
My Updated Code
lock = threading.Lock()
def call_threads():
t1 = threading.Thread(target=main_function,args=(window1,))
t1.start()
t2 = threading.Thread(target=time_calc,args=(window2,))
t1.start()
def main_function(window1):
#Gets user input
while True:
data = window1.addstr(y,x,"Type something in!")
data = window1.getstr(y,x,5)
lock.acquire()
window1.erase()
txt = "You said: "+data
window1.addstr(y,x,txt)
lock.release()
def time_calc(window2):
current_count = 0
while True:
time += 1
text = "Time Count: "+str(time)
lock.acquire()
window2.erase()
window2.addstr(y,x,text)
lock.release()
time.sleep(1)
If there is anything else that may have caused this error, please comment it!
Hey I am trying to have a loop be pausable from user input like having a input box in the terminal that if you type pause it will pause the loop and then if you type start it will start again.
while True:
#Do something
pause = input('Pause or play:')
if pause == 'Pause':
#Paused
Something like this but having the #Do something continually happening without waiting for the input to be sent.
Ok I get it now, here is a solution with Threads:
from threading import Thread
import time
paused = "play"
def loop():
global paused
while not (paused == "pause"):
print("do some")
time.sleep(3)
def interrupt():
global paused
paused = input('pause or play:')
if __name__ == "__main__":
thread2 = Thread(target = interrupt, args = [])
thread = Thread(target = loop, args = [])
thread.start()
thread2.start()
You can't directly, as input blocks everything until it returns.
The _thread module, though, can help you with that:
import _thread
def input_thread(checker):
while True:
text = input()
if text == 'Pause':
checker.append(True)
break
else:
print('Unknown input: "{}"'.format(text))
def do_stuff():
checker = []
_thread.start_new_thread(input_thread, (checker,))
counter = 0
while not checker:
counter += 1
return counter
print(do_stuff())
I am working on a Python scripts that kicks off a thread with a loop and a raw_input so that user can enter commands. After this thread starts, main program starts a loop with another raw_input so that the user can enter commands.
How can this be organized so that the commands being inputted via console goes to the correct raw_input (main thread/concurrent thread)? At the moment, all inputs in the console are going to the main thread only.
Thanks
Example
import threading
def commThread():
while True:
chatAcceptance = raw_input("User")
t1 = threading.Thread(target=commThread)
t1.start()
while True:
userInput = raw_input("\nPlease insert a command:\n")
So this can be done via lock. I did a small code example that shows how to swap between one "scope" to the other using the raw_input.
import threading
lock = threading.Lock()
def inputReader(thread, prompt):
userInput = raw_input(prompt)
print thread + " " + userInput + "\n"
return userInput
def myThread1():
global lock
while True:
lock.acquire()
print "thread 1 got the lock\n"
while True:
threadInput = inputReader("thread 1", "from thread 1\n")
if threadInput == "release":
lock.release()
print "thread 1 released the lock\n"
break
def myThread2():
global lock
while True:
lock.acquire()
print "thread 2 got the lock\n"
while True:
threadInput = inputReader("thread 2", "from thread 2\n")
if threadInput == "release":
lock.release()
print "thread 2 released the lock\n"
break
t1 = threading.Thread(target=myThread1).start()
t2 = threading.Thread(target=myThread2).start()