使用 Event.set() Inside a Thread Class 方法在 GPIO 输入中断触发时暂停线程
Pausing a Thread When GPIO Input Interrupt Triggers using Event.set() Inside a Thread Class Method
大家好,我正在尝试调用线程内的方法 class,该方法应在该线程内设置事件标志,导致线程在设置事件时停止 运行ning .当前代码可以正常工作并调用函数,但事件标志似乎并未在线程内部触发。
当在 GUI 上按下按钮时,线程负责对 运行 的操作,但如果设置了事件,则不应 运行。
我的代码的最小版本:
import threading
import time
GPIO.setup(18, GPIO.IN, pull_up_down=GPIO.PUD.UP)
global run = 0
class Pump_Thread(threading.Thread):
def __init__(self, interval=0.5):
super(Pump_Thread, self).__init__()
self._stop_event = threading.Event()
self.interval = interval
Pump_threads = threading.Thread(target=self.run, daemon=True)
Pump_threads.start()
def stop(self):
self._stop_event.set()
print("Things have stopped yo...")
def resume(self):
self._stop_event.clear()
print("And Now Things will resume")
def run(self)
while not self._stop_event.is_set():
if (run == 1):
#doing some stuff when bit set#
print("Yeah Yeah, I'm running")
class Page1(Page):
def __init__(self, *args, **kwargs):
#Some Initializing methods to load buttons and graphics
self.start_btn=tk.Button(self,height=32,width =80,command=self.Start)
self.start_btn.place(x=50, y=50)
self.reset_btn=tk.Button(self,height=32,width =80,command=self.Reset)
self.reset_btn.place(x=50, y=80)
def Start(self):
global run
run = 1 #<------Set Bit for code to run
def Reset(self):
d = Pump_Thread()
d.resume() #<-----Run Method inside thread
class Monitor_Thread(threading.Thread):
def __init__(self, interval=0.5):
self.interval = interval
Monitor_Threads = threading.Thread(target=self.Monitor_Thread, daemon=True)
Monitor_Threads.start()
def run(self)
while True:
if Condition == True:
d = Pump_Thread()
d.stop() #<-----Run Method inside thread
class Interrupt_Class(page):
def Input(self):
d = Pump_Thread()
d.stop() #<-----Run Method inside thread
GPIO.add_event_detect(18, GPIO.FALLING, callback=Input, bouncetime=300)
class MainView(tk.Frame):
def __init__(self, *args, **kwargs):
tk.Frame.__init__(self, *args, *kwargs)
super().__init__()
p1 = Page1(self) #Other Pages Added here with navigation buttons to raise the page to the front of the GUI#
p1.show()
if __name__ == "__main__":
root = tk.TK()
main = MainView(root)
main.pack(side="top", fill="both", expand=True)
root.wm_geometry("400x400")
root.attributes("-fullscreen", False)
Thread1 = Pump_Thread()
Thread2 = Monitor_Thread()
root.mainloop()
当中断被触发时,打印“Things have stopped yo...”,因此调用了该方法,但是当按下 GUI 按钮时该过程仍然开始,这意味着事件没有设置。这是什么原因?
您正在呼叫:
d = Pump_Thread()
每次调用之前:d.stop()
这只会使该线程停止。
Pump_Thread
是如何实例化的,您在哪里存储对它的引用?
事实上,您没有显示您的任何 类 是如何实例化的。
你的错误似乎层出不穷。
您需要查看 Whosebug 上有关如何创建和管理线程的许多示例。
您可以尝试这样的操作:
class Pump_Thread(threading.Thread):
def __init__(self, interval=0.5):
super().__init__()
self._stop_event = threading.Event()
self.interval = interval
def stop(self):
self._stop_event.set()
print("Things have stopped yo...")
def resume(self):
self._stop_event.clear()
print("And Now Things will resume")
def run(self)
while not self._stop_event.is_set():
print("Yeah Yeah, I'm running")
# other parts elided
if __name__ == "__main__":
root = tk.TK()
main = MainView(root)
Thread1 = Pump_Thread()
Thread1.start()
但现在所有其他需要启动和停止的地方 Pump_Thread
都需要访问 Thread1
。所以你应该将它传递给创建的对象。
class Interrupt_Class(page):
def __init__(self, pump):
self.pump = pump
def Input(self):
self.pump.stop() #<-----Run Method inside thread
ic = Interrupt_Class(Thread1)
大家好,我正在尝试调用线程内的方法 class,该方法应在该线程内设置事件标志,导致线程在设置事件时停止 运行ning .当前代码可以正常工作并调用函数,但事件标志似乎并未在线程内部触发。
当在 GUI 上按下按钮时,线程负责对 运行 的操作,但如果设置了事件,则不应 运行。
我的代码的最小版本:
import threading
import time
GPIO.setup(18, GPIO.IN, pull_up_down=GPIO.PUD.UP)
global run = 0
class Pump_Thread(threading.Thread):
def __init__(self, interval=0.5):
super(Pump_Thread, self).__init__()
self._stop_event = threading.Event()
self.interval = interval
Pump_threads = threading.Thread(target=self.run, daemon=True)
Pump_threads.start()
def stop(self):
self._stop_event.set()
print("Things have stopped yo...")
def resume(self):
self._stop_event.clear()
print("And Now Things will resume")
def run(self)
while not self._stop_event.is_set():
if (run == 1):
#doing some stuff when bit set#
print("Yeah Yeah, I'm running")
class Page1(Page):
def __init__(self, *args, **kwargs):
#Some Initializing methods to load buttons and graphics
self.start_btn=tk.Button(self,height=32,width =80,command=self.Start)
self.start_btn.place(x=50, y=50)
self.reset_btn=tk.Button(self,height=32,width =80,command=self.Reset)
self.reset_btn.place(x=50, y=80)
def Start(self):
global run
run = 1 #<------Set Bit for code to run
def Reset(self):
d = Pump_Thread()
d.resume() #<-----Run Method inside thread
class Monitor_Thread(threading.Thread):
def __init__(self, interval=0.5):
self.interval = interval
Monitor_Threads = threading.Thread(target=self.Monitor_Thread, daemon=True)
Monitor_Threads.start()
def run(self)
while True:
if Condition == True:
d = Pump_Thread()
d.stop() #<-----Run Method inside thread
class Interrupt_Class(page):
def Input(self):
d = Pump_Thread()
d.stop() #<-----Run Method inside thread
GPIO.add_event_detect(18, GPIO.FALLING, callback=Input, bouncetime=300)
class MainView(tk.Frame):
def __init__(self, *args, **kwargs):
tk.Frame.__init__(self, *args, *kwargs)
super().__init__()
p1 = Page1(self) #Other Pages Added here with navigation buttons to raise the page to the front of the GUI#
p1.show()
if __name__ == "__main__":
root = tk.TK()
main = MainView(root)
main.pack(side="top", fill="both", expand=True)
root.wm_geometry("400x400")
root.attributes("-fullscreen", False)
Thread1 = Pump_Thread()
Thread2 = Monitor_Thread()
root.mainloop()
当中断被触发时,打印“Things have stopped yo...”,因此调用了该方法,但是当按下 GUI 按钮时该过程仍然开始,这意味着事件没有设置。这是什么原因?
您正在呼叫:
d = Pump_Thread()
每次调用之前:d.stop()
这只会使该线程停止。
Pump_Thread
是如何实例化的,您在哪里存储对它的引用?
事实上,您没有显示您的任何 类 是如何实例化的。
你的错误似乎层出不穷。
您需要查看 Whosebug 上有关如何创建和管理线程的许多示例。
您可以尝试这样的操作:
class Pump_Thread(threading.Thread):
def __init__(self, interval=0.5):
super().__init__()
self._stop_event = threading.Event()
self.interval = interval
def stop(self):
self._stop_event.set()
print("Things have stopped yo...")
def resume(self):
self._stop_event.clear()
print("And Now Things will resume")
def run(self)
while not self._stop_event.is_set():
print("Yeah Yeah, I'm running")
# other parts elided
if __name__ == "__main__":
root = tk.TK()
main = MainView(root)
Thread1 = Pump_Thread()
Thread1.start()
但现在所有其他需要启动和停止的地方 Pump_Thread
都需要访问 Thread1
。所以你应该将它传递给创建的对象。
class Interrupt_Class(page):
def __init__(self, pump):
self.pump = pump
def Input(self):
self.pump.stop() #<-----Run Method inside thread
ic = Interrupt_Class(Thread1)