在Python状态事件中杀死线程

时间:2019-07-18 13:48:11

标签: python multithreading raspberry-pi kill

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

RPi与包含3个按钮和6个LED的板连接。每个LED都是一个状态。如果正确按下按钮(例如和),则状态将切换。我的电路板可以不使用RPi进行工作,而这仅仅是一个硬件解决方案。但是对于演示文稿,必须在软件中也可以做到。而这正是问题所在。如果我从硬件切换到软件,则该线程将处于活动状态;如果我从软件切换回硬件,则该线程仍处于状态。再次切换到该软件,该线程将重新启动。但是旧状态(LED)并未删除。因此看起来好像有两个状态处于活动状态。

我只想从硬件切换到软件,然后再无任何问题。您看到的代码是此开关为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正常工作
  • 从硬件切换到软件效果不佳

2 个答案:

答案 0 :(得分:0)

1。)t._stop()将不起作用,因为在主线程中正在调用它。需要从线程本身调用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的对象是。每次调用函数时,都会创建一个NEW线程。您需要在调用停止的同一线程对象上调用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()

答案 1 :(得分:0)

因此,将您的代码放入我的代码后,我还有其他一些问题。为了向您展示问题所在,我发布了主函数的第一个定义。这里有您的类MyThread,在这个类中,我将定义叫Configuration。

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

非常感谢您的帮助。如果该程序最终成功,我将非常高兴。