【问题标题】:Kill a Thread in Python State Event在 Python 状态事件中杀死一个线程
【发布时间】:2019-07-18 13:48:11
【问题描述】:

我正在我的 RPi 上使用 Python,现在我需要帮助。问题是在我的程序的后台,一个线程正在做他的工作。这项工作是一个有定义的状态事件程序。但是我需要在 else 中杀死这个线程 t。我认为它可以与 stop、clear 或类似的东西一起使用,但它不起作用。如果您需要完整的代码,只需编写它。这是我的代码中唯一不起作用的东西。

RPi 与一块板连接,该板包括 3 个按钮和 6 个 LED。每个 LED 都是一个状态。如果按钮按下正确(例如和),状态将切换。我的板子在没有 RPi 的情况下工作,然后它只是一个硬件解决方案。但是对于演示文稿,在软件中也必须做到这一点。这正是问题所在。如果我从硬件切换到软件,则线程将处于活动状态,如果我从软件切换回硬件,则线程仍处于状态。再次切换到软件,线程重新启动。但是旧状态(LED)没有被删除。所以看起来有 2 个状态处于活动状态。

我只想从硬件切换到软件,然后再切换回来,没有任何问题。您看到的代码是这个开关作为 GUI

def GUI_Function():

def HW_SW_Mode():  

        t = threading.Thread(target=Main_Function)

        t.daemon = True

        if not Led_HW_SW_Mode.is_lit:                      
                Led_HW_SW_Mode.on()                     
                ledButton2["text"] = "Software aktiv"  
                t.start()

        else:                                        
                t._stop()
                RPi.GPIO.output(Led_List, RPi.GPIO.LOW)       
                Led_HW_SW_Mode.off()                    
                ledButton2["text"] = "Hardware aktiv"  

def close():                                           
        RPi.GPIO.cleanup()                             
        win.destroy()                                   
  • 主程序工作
  • GPIO 有效
  • 从硬件切换到软件效果不佳

【问题讨论】:

    标签: python multithreading raspberry-pi kill


    【解决方案1】:

    1.) t._stop() 将不起作用,因为它正在主线程中被调用。需要从线程本身调用停止。这是一个可以被另一个线程停止的线程的示例。

    class MyThread(threading.Thread):
        def __init__(self, *args, **kwargs):
            super(MyThread, self).__init__(*args, **kwargs)
            self.running = False
    
        def run(self): // this is where the main_function definition goes.
            self.running = True
            while self.running:
                print "I am still alive"
                time.sleep(10)
    
            print "I am stopping"
    
        def stop(self):
            self.running = False
    

    2.) t._stop 仍然无法与上述更改一起使用,因为它是在不同的对象上调用的,然后是调用 t.start 的对象。每次调用函数时,都会创建一个新线程。您需要在调用 stop 的同一线程对象上调用 stop。

    t = None // Place holder for thread. Find a way to make this not global if you can. 
    
    def HW_SW_Mode():
        global t  // this means that assigning to t will affect the global t 
                  // instead of pythons default to create a new t in the 
                  // current scope which shadows the global t. Better to find 
                  // a way to make it not global, but not a big deal if the code
                  // is simple enough. 
    
        if not Led_HW_SW_Mode.is_lit:                      
                Led_HW_SW_Mode.on()                     
                ledButton2["text"] = "Software aktiv"  
                t = MyThread()
                t.daemon = True
                t.start()
        else:                                        
                t.stop()
                RPi.GPIO.output(Led_List, RPi.GPIO.LOW)       
                Led_HW_SW_Mode.off()                    
                ledButton2["text"] = "Hardware aktiv"  
                print "Waiting for thread to return. If you get stuck"
                print " here something is wrong with the run loop in your"
                print " thread not returning when the running flag is set False"
                t.join()
    

    【讨论】:

    • 你能回答我的问题吗?使用您的代码,我收到了其他问题...我需要修复它们。
    【解决方案2】:

    所以在将您的代码放入我的代码之后,我又遇到了一些问题。为了向您展示问题所在,我发布了我的 main 函数的第一个定义。这里我们有你的 MyThread 类,在这个类中我称之为我的定义配置。

    class MyThread(threading.Thread):

    def __init__(self, *args, **kwargs):
        super(MyThread, self).__init__(*args, **kwargs)
        self.running = False
    
    def run(self): # this is where the main_function definition goes.
        self.running = True
        while self.running:
            print ("I am still alive")
            Configuration()
    
        print ("I am stopping")
    
    def stop(self):
        self.running = False
    

    这里我们实际上有我的主要功能的第一个定义。您会看到 else 指向配置。那应该是一个状态事件机器,所以它有一个无限循环。如果我单击 GUI 按钮并关闭 LED,我需要从那里找到出路。使用您的附加线程,我会陷入软件模式,如果我想返回硬件模式,GUI 会冻结。在终端中是一个无限循环的 hello,它是用 Configuration 编写的。我怎么能解决这个问题?我该如何摆脱这种情况并且 GUI 停止冻结。

    def Configuration():

    print("Hello")
    Led_Configuration.on()                              
    time.sleep(.1)
    if button_Next.is_pressed:
            if (button_IN1.is_pressed and button_IN2.is_pressed):
                Led_Configuration.off()
                RPi.GPIO.output(Led_List, RPi.GPIO.LOW)             # Alle LEDs ausschalten
                time.sleep(.2)
                Wire_Library()
            else:
                Configuration()
    else:
            Configuration()   
    

    这又是包含您提供的代码的 GUI。

    def GUI_Function():

    t = None
    
    def HW_SW_Mode():
    
            global t
    
            if not Led_HW_SW_Mode.is_lit:         
                    Led_HW_SW_Mode.on()                 
                    ledButton2["text"] = "Software aktiv"
                    t = MyThread()
                    t.daemon = True
                    t.start()
    
            else:                         
                    t.stop()
                    RPi.GPIO.output(Led_List, RPi.GPIO.LOW)            
                    Led_HW_SW_Mode.off()                
                    ledButton2["text"] = "Hardware aktiv"
                    t.join()
    

    非常感谢您的帮助。如果这个程序最终能奏效,我会非常高兴。

    【讨论】:

      猜你喜欢
      • 2022-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-19
      • 1970-01-01
      • 2012-07-11
      • 1970-01-01
      相关资源
      最近更新 更多