stop multiple threads - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: General Coding Help (https://python-forum.io/forum-8.html) +--- Thread: stop multiple threads (/thread-14066.html) |
stop multiple threads - jeuvrey - Nov-13-2018 Hello, I work with python 3.7 and want to develop a litle animation allowing a dot to move thanks to recorded data. i create 2 threads, one thread is used to "catch" new data (a simple incrementation but recorded from a tracking system later) and an other thread to run the dot move. I want to stop the 2 threads and the widget (fen) with an event (a button QUIT) but i don't succeed: any idea? my code is below Thanks! # moving point (see p 366 example in python book) from tkinter import * import time,threading x,y= 10,10# global variable class threadCollectData(threading.Thread): def __init__(self): threading.Thread.__init__(self) self.collect=1 def run(self): global x,y # to modify x, y in a function while self.collect==1: x+=0.00001 y=y def stop(self): # method to stop the thread self.collect=0 class threadMovingPoint(threading.Thread): def __init__(self,canevas,Mvt_pt): threading.Thread.__init__(self) self.can=canevas self.Mvt_pt=Mvt_pt # self.anim=1 #flag to launch animation def run(self): while self.anim==1: self.can.coords(self.Mvt_pt,x-5,y-5,x+5,y+5) time.sleep(1) def stop(self): self.anim=0 fen=Tk() fen.title('moving point') can=Canvas(fen,width=400,height=250,bg="white") can.pack(side=LEFT) movingPoint=can.create_oval(10,10,20,20,fill='red') t_C=threadCollectData() t_M=threadMovingPoint(can,movingPoint) Button(fen,text='Move',command=t_M.start).pack(side=BOTTOM) #bou1=Button(fen,text='stop Thread 1', command=t_M.stop) #bou1.pack(side=BOTTOM) #bou2=Button(fen,text='stop Thread 2', command=t_C.stop) #bou2.pack(side=BOTTOM) t_C.start() bou3=Button(fen,text='QUIT', command=???) # <-- how to close the threads t_M and t_C and fen? bou3.pack(side=BOTTOM) fen.mainloop() # Démarrage du gestionnaire d'évenements fen.destroy() RE: stop multiple threads - Gribouillis - Nov-13-2018 For the threadMovingPoint, I suggest to use a Condition object instead of time.sleep() class threadMovingPoint(threading.Thread): def __init__(self,canevas,Mvt_pt): threading.Thread.__init__(self) self.can=canevas self.Mvt_pt=Mvt_pt # self.cond = threading.Condition() self.anim=1 #flag to launch animation def run(self): with self.cond: while self.anim: self.can.coords(self.Mvt_pt,x-5,y-5,x+5,y+5) self.cond.wait(timeout=1.0) def stop(self): with self.cond: self.anim=0 self.cond.notify() self.join()For the other thread, I'm not sure it is a good idea to have a loop running indefinitely without any pause. Don't you want to add some sleeping time in the loop? I suppose that in the future, if you have a tracking system, there will be some sort of blocking select() call. You could perhaps model this with another Condition instance for the time being.
RE: stop multiple threads - jeuvrey - Nov-14-2018 hello, Thanks for your response, i think your advice will improve my code but my main problem is already here, how can i stop the two threads with one event (a quit button)? thanks! RE: stop multiple threads - Gribouillis - Nov-14-2018 (Nov-14-2018, 09:29 AM)jeuvrey Wrote: but my main problem is already here,Doesn't my code sto the threadMovingPoint when you invoke the stop function? Or perhaps you need to write a command to invoke the stop functions? RE: stop multiple threads - woooee - Nov-14-2018 Here it is using multiprocessing if it helps. https://pymotw.com/3/multiprocessing/index.html import sys if 3 == sys.version_info[0]: ## 3.X is default if dual system import tkinter as tk ## Python 3.x else: import Tkinter as tk ## Python 2.x import time from multiprocessing import Process class TestClass(): def test_f(self, spaces=1): ctr = spaces while True: ctr += 1 print(" "*spaces, ctr) time.sleep(1.0) def tk_quit(self): root=tk.Tk() tk.Button(root, text="Quit", command=root.quit, width=10).grid() root.mainloop() if __name__ == '__main__': ## run functions in the background CT=TestClass() p = Process(target=CT.test_f) p.start() ## run same function in another process to ## simulate 2 different processes p2 = Process(target=CT.test_f, args=(10,)) p2.start() CT.tk_quit() print("terminate process") if p.is_alive(): p.terminate() p.join() if p2.is_alive(): p2.terminate() p2.join() RE: stop multiple threads - jeuvrey - Nov-15-2018 Thanks, It is fun because i just think about using multiprocessing ten minutes ago. Maybe this solution is more suited to my situation. I want to move a dot with data coming from a tracking system. Maybe it will be useful for some people, here is my code using 2 threads and kill them with a STOP button. from tkinter import * import time,threading x,y= 10,10# global variable def threadCollectData(e): global x,y # to modify x, y in a function while not e.isSet(): # while evt not set to 1 x+=1 y=y print('Th 1 run') time.sleep(0.01) def threadMovingPoint(e,can,movingPoint): global x,y while not e.isSet(): can.coords(movingPoint,x-5,y-5,x+5,y+5) print('Th 2 run') #time.sleep(0.1) fen=Tk() fen.title('moving point') can=Canvas(fen,width=400,height=250,bg="white") can.pack(side=LEFT) movingPoint=can.create_oval(10,10,20,20,fill='red') evt=threading.Event() # Thread evenement creation t1= threading.Thread(target=threadCollectData,args=(evt,)) # Thread 1 creation t1.start() t2= threading.Thread(target=threadMovingPoint,args=(evt,can,movingPoint)) # Thread 2 creation Button(fen,text='Move',command=t2.start).pack(side=BOTTOM) # start the t1 thread bou3=Button(fen,text='STOP', command=evt.set) # Evt set to 1 will stop the 2 threads bou3.pack(side=BOTTOM) fen.mainloop() # Start evement managerThanks! |