how to break a thread function in python - python

I need a help to stop getCPUtemperature(): function together with robot() function.
def getCPUtemperature():
while True:
res = os.popen('vcgencmd measure_temp').readline()
temp1=int(float(res.replace("temp=","").replace("'C\n","")))
temp2= 9.0/5.0*temp1+32
print temp1,"C", "\n", temp2,"F"
time.sleep(0.5)
if __name__ == '__main__':
try:
#Thread(target = robot).start()
Thread(target = getCPUtemperature).start()
Thread(target = robot).start()
except KeyboardInterrupt:
# CTRL+C exit, turn off the drives and release the GPIO pins
print 'Terminated'
stop_movement()
raw_input("Turn the power off now, press ENTER to continue")
GPIO.cleanup()
quit()strong text

make your child threads daemon and keep the main thread alive to waiting them finish or a ctrl-c pressed.
try the following code:
if __name__ == '__main__':
#Thread(target = robot).start()
t1 = Thread(target = getCPUtemperature)
t1.daemon = True # in daemon mode
t1.start()
t2 = Thread(target = robot)
t2.daemon = True
t2.start()
try:
while threading.active_count() > 1:
time.sleep(1)
except KeyboardInterrupt:
# CTRL+C exit, turn off the drives and release the GPIO pins
print 'Terminated'
stop_movement()
raw_input("Turn the power off now, press ENTER to continue")
GPIO.cleanup()
quit()

Related

python problem using multithread with blocking

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()

Python: is it possible to start and stop a while loop from another thread?

I am trying to start and stop a while loop within a thread from another thread. But no matter what I do I can't get it to work properly. I am actually able to stop a while loop in another thread, but then I am unable to start the while loop again. Is this even possible? In it's core it seems to be a simple question, but I have been unable to find a proper answer to it. Maybe I just have to rethink my code architecture? Or maybe there are other tools (for threading or otherwise) which I should use?
Here is try number 1, which can stop a while loop, but not start it again:
import threading
import time
first_time = True
def read_sensors():
while run_event2.is_set():
run_event2.wait()
time.sleep(0.5)
print("sensor read")
def back_end():
global first_time
while run_event.is_set():
time.sleep(1)
print("back-end")
if first_time:
first_time = False
time.sleep(5)
print("clear sensors")
run_event2.clear()
time.sleep(2)
print("set sensors")
run_event2.set()
time.sleep(5)
print("clear sensors")
run_event2.clear()
time.sleep(3)
print("set sensors")
run_event.set()
run_event = threading.Event()
run_event2 = threading.Event()
run_event.set()
run_event2.set()
t1 = threading.Thread(target = read_sensors)
t2 = threading.Thread(target = back_end)
t1.start()
time.sleep(.5)
t2.start()
time.sleep(5)
try:
while 1:
time.sleep(.1)
except KeyboardInterrupt:
print("closing threads")
run_event.clear()
run_event2.clear()
t1.join()
t2.join()
print("threads successfully closed")
Here is another code example where I am using a global variable to stop a while loop, but again I am unable to figure out how to start the while loop again.
import threading
import time
run_event2 = True
run_event = True
def read_sensors():
global run_event2
while run_event2:
time.sleep(1)
print("run_event2 value: {0}".format(run_event2))
print("sensor read")
def back_end():
global run_event
global run_event2
while run_event:
time.sleep(1)
print("back-end")
time.sleep(5)
run_event2 = False
time.sleep(5)
run_event2 = True
t1 = threading.Thread(target = read_sensors)
t2 = threading.Thread(target = back_end)
t1.start()
time.sleep(.5)
t2.start()
time.sleep(5)
try:
while 1:
time.sleep(.1)
except KeyboardInterrupt:
print("closing threads")
run_event2 = False
run_event = False
t1.join()
t2.join()
print("threads successfully closed")
Are you trying to achieve this type of an output?
If Yes please try calling one function within another, if not please manually compose an output that you would like to achieve. Like calling another fn when sensor is off
See the modified code for the above oupput
import threading
import time
run_event2 = True
run_event = True
def read_sensors():
global run_event2
while run_event2:
time.sleep(1)
print("run_event2 value: {0}".format(run_event2))
print("sensor read")
if run_event2 == False:
back_end()
def back_end():
global run_event
global run_event2
while run_event:
time.sleep(1)
print("back-end")
time.sleep(5)
run_event2 = False
time.sleep(5)
run_event2 = True
read_sensors()
t1 = threading.Thread(target = read_sensors)
t2 = threading.Thread(target = back_end)
t1.start()
time.sleep(.5)
t2.start()
time.sleep(5)
try:
while 1:
time.sleep(.1)
except KeyboardInterrupt:
print("closing threads")
run_event2 = False
run_event = False
t1.join()
t2.join()
print("threads successfully closed")

Python pause loop on user input

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())

Why are my multiprocesses not starting without time.sleep in main?

I have some background task that i want to start an be able to safely quit by user input.
To do that i have a thread in which a process pool with a continous task is started. There is a input lock to stop printing and to wait for user input and a event to stop the whole process.
What surprises me is that the processes seem to start and do their work if there is a time.sleep after the start of the thread with processpool (6th line in main).
import multiprocessing as mp
import time
import threading as tr
def init(e, l):
global stop_event
global input_lock
stop_event = e
input_lock = l
def stupid_task(n):
while not stop_event.is_set():
with input_lock:
print(n)
time.sleep(2)
def test_mng(n, event, lock):
with mp.Pool(n, initializer=init, initargs=(event, lock,)) as p:
print("before")
p.map(stupid_task, range(1, n + 1))
print("after")
p.close()
p.join()
def main():
i_lock = mp.Lock()
s_event = mp.Event()
thread = tr.Thread(target=test_mng, args=(3, s_event, i_lock))
init(s_event,i_lock)
thread.start()
time.sleep(1) # if this line is commented out only "before" is printed
while not stop_event.is_set():
input("")
with input_lock:
print("stopped")
eingabe = input("type q to quit")
if eingabe == "q":
stop_event.set()
if __name__ == "__main__":
main()
I ask myself what is stopping the process pool from doing it's work. Do i do something fundamentally wrong? The time.sleep seems a little bit hacky.
I my opinion, you are running your script from an IDE (like PyCharm), but not from the Console. Your IDE is catching the keyboard events.
You can simplify the processing:
The main process can wait for the user input,
The thread can do the "stupid task".
Here is a possible solution:
# coding: utf-8
import multiprocessing as mp
import threading as tr
import time
stop_event = None
def init(event):
global stop_event
stop_event = event
def stupid_task(n):
while not stop_event.is_set():
print(n)
time.sleep(2)
def test_mng(n, event):
with mp.Pool(n, initializer=init, initargs=(event,)) as p:
print("before")
p.map(stupid_task, range(1, n + 1))
print("after")
p.close()
p.join()
def main():
print("type 'q' <ENTER> to quit")
s_event = mp.Event()
init(s_event)
thread = tr.Thread(target=test_mng, args=(3, s_event,))
thread.start()
while not stop_event.is_set():
c = input("")
if c in "qQ":
stop_event.set()
if __name__ == "__main__":
main()

raw_input with Main thread and concurrent thread in Python

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()

Categories