Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在线程类方法中使用Event.set()触发GPIO输入中断时暂停线程_Python_Multithreading_Events_Interrupt_Thonny - Fatal编程技术网

Python 在线程类方法中使用Event.set()触发GPIO输入中断时暂停线程

Python 在线程类方法中使用Event.set()触发GPIO输入中断时暂停线程,python,multithreading,events,interrupt,thonny,Python,Multithreading,Events,Interrupt,Thonny,大家好,我正在尝试调用thread类中的一个方法,该方法应该在该线程中设置一个事件标志,导致该线程在设置事件时停止运行。当前代码可以工作,并调用函数,但事件标志似乎不会在线程内部触发 线程负责在按下GUI上的按钮时运行的操作,但如果设置了事件,则不应运行该操作 我的代码的最低版本: import threading import time GPIO.setup(18, GPIO.IN, pull_up_down=GPIO.PUD.UP) global run = 0 class Pump_

大家好,我正在尝试调用thread类中的一个方法,该方法应该在该线程中设置一个事件标志,导致该线程在设置事件时停止运行。当前代码可以工作,并调用函数,但事件标志似乎不会在线程内部触发

线程负责在按下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()
导入线程
导入时间
GPIO.setup(18,GPIO.IN,上下拉=GPIO.PUD.up)
全局运行=0
泵类螺纹(螺纹.螺纹):
定义初始值(自,间隔=0.5):
超级(泵螺纹,自紧)。\uuuuu初始
self.\u stop\u event=threading.event()
self.interval=间隔
Pump_threads=threading.Thread(target=self.run,daemon=True)
泵螺纹。启动()
def停止(自):
self.\u stop\u event.set()
打印(“事情已经停止了…”)
def恢复(自我):
self.\u stop\u event.clear()
打印(“现在一切都将恢复”)
def运行(自我)
而不是自我。停止事件。是否设置()
如果(运行==1):
#在设置位时做一些事情#
打印(“是的,我在跑步”)
班级第1页(第页):
定义初始化(self,*args,**kwargs):
#加载按钮和图形的一些初始化方法
self.start\u btn=tk.按钮(self,高度=32,宽度=80,命令=self.start)
自启动位置(x=50,y=50)
self.reset\u btn=tk.按钮(self,高度=32,宽度=80,命令=self.reset)
自复位位置(x=50,y=80)
def启动(自):
全球运行
运行=1#您正在呼叫:

d = Pump_Thread()
每次调用之前:
d.stop()
,这只会使该线程停止

Pump\u Thread
是如何实例化的,您在哪里存储对它的引用


事实上,您没有显示任何类是如何实例化的。

您似乎有许多错误堆积在一起

您需要查看有关stackoverflow的许多示例,了解如何创建和管理线程

您可以尝试以下方法:

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()
但是现在所有其他需要启动和停止
泵送螺纹的位置都需要访问
螺纹1
。因此,您应该将其传递到创建的对象中

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)
类中断\u类(第页):
def u u初始(自,泵):
自泵=泵
def输入(自):

self.pump.stop()#好的,现在我可以看到正在实例化的
pump_线程
,那么
target=self.pump_run
是什么意思?这肯定会产生错误吗?好的,您使用的是
target=self.run
,但从
线程
派生时,这是隐式的。请看我的另一个答案。对不起,这只是在减少问题代码时的一个输入错误。代码大约有1400行,运行时没有错误或警告,但问题的焦点是新添加的内容,即当从另一个类调用该方法时,为什么事件没有设置为。它不产生错误或警告,并打印消息,但未设置事件。但是,当在类内调用该方法时,事件为setYes,
停止
恢复
方法
设置
清除
线程.event
,但仅适用于所引用的实例。当您调用
stop
clear
时,您应该指的是在调用
mainloop()
之前创建的
Thread1
实例。很抱歉,我不认为reduce code版本需要它。我对该语言相当陌生,因此犯简单错误或误解新术语对我来说是相当常见的。我承认,对象的使用令人困惑,我希望事件类似于布尔值,您可以通过在类中的任何位置调用该方法在类中设置,它类似于布尔值,但它是每个实例的布尔值。您的
run
变量是一个全局变量,它可以在所有实例中工作,但您必须知道,作为一名程序员,您必须非常非常非常努力地避免使用全局变量。事实上,实例变量和类变量之间的混淆已经不止一次地愚弄了我。但是在这种情况下,globals的使用是有益的,因为bit在不同的页面上被监控,以显示它是否为真,并且它只通过用户交互来改变。你能解释一下
ic=Interrupt\u Class(Thread1)
的作用吗?我的意思是你正在将引用
Thread1
传递到
Interrupt\u Class
的一个实例中,这样它就可以
self.pump
引用
Thread1
的正确实例,然后
self.pump.stop()
将按您的意愿执行。