使用多个线程多次调用一个方法

时间:2017-03-10 16:50:00

标签: python multithreading raspberry-pi gpio

我想要一个LED闪光,而我的覆盆子正在做一些工作。我在我的Python脚本中使用了一个用于LED的线程。

初始代码:

import RPi.GPIO
import time
import threading

pinLED = 10
pinButton = 12

GPIO.setmode(GPIO.BOARD)
GPIO.setup(pinLED, GPIO.OUT)
GPIO.setup(pinButton, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.output(pinLED, 0)

线程的方法:

working = False
def flash():
    status = 0
    while working:
        time.sleep(0.5)
        if status == 0:
            GPIO.output(pinLED, 1)
            status = 1
        else:
            GPIO.output(pinLED, 0)
            status = 0|
    GPIO.output(pinLED, 0)

逻辑:

try:
    while True:
        time.sleep(0.02) #found out that 0.02 is a good value to get every tiny button push and save resources

        if GPIO.input(pinButton) == 1:
            t = threading.Thread(target=flash)
            working = True
            t.start()

            time.sleep(5) #work would be here
            working = False
            t.join()

except Exception as e:
    print(e)
finally:
    GPIO.cleanup()

当我第一次启动脚本并按下按钮时,一切正常,LED指示灯闪烁。但是当我第二次按下按钮而没有重新启动脚本时,指示灯不会闪烁。我打印了一些调试消息并发现,调用了t.start(),但由于某种原因它什么也没做,也没有抛出异常。每次再次按下按钮时,LED是否开始闪烁?

1 个答案:

答案 0 :(得分:1)

我发现没有逻辑错误,我确认它有效,但使用了以下更改:

  1. main_thread内开始if __name__ == '__main__': 我建议同时移动此GPIO内的所有block次来电。
  2. 避免将启动时执行的代码置于if __name__ == '__main__':

    之外
      

    来自文档:    安全导入主模块    应该使用if __name__ =='__ main__'来保护程序的“入口点”:

    1. join()之后添加working = False,这保证线程已经终止,因为它再次启动它。

      working = False  
      t.join()  
      
    2. 我建议将def flash()更改为以下内容:
      使用threading.Event()代替global Instance并将其与pinLED一起传递。 这概括了def flash(...)并允许其与不同的pinLED一起使用,甚至是并行的。 将status定义为threading.local()线程安全,因此实例的值对于不同的线程将是不同的 例如:

      def flash(pinLED, flashing):
          status = threading.local()
          status.LED = False
          while flashing.is_set():
              status.LED = not status.LED
              GPIO.output(pinLED, int(status.LED))
              time.sleep(0.5)
      
          GPIO.output(pinLED, 0)
      

      main_thread

      的更改
      def main_thread():
          flashing = threading.Event()
          flashing.clear()
      
          try:
              while True:
                  time.sleep(0.02)  
                  if GPIO.input(pinButton) == 1:
                      t = threading.Thread(target=flash, args=(pinLED, flashing,))
                      flashing.set()
                      t.start()
      
                      time.sleep(2)  # work would be here
      
                      flashing.clear()
                      t.join()
          ...  
      

      使用Python测试:3.4.2