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

标签 python multithreading raspberry-pi gpio

我想要一个 LED 闪烁,同时我的 Raspberry 上正在完成一些工作。我在 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 闪烁。但是当我第二次按下按钮时,没有重新启动脚本,LED 不闪烁。我打印了一些调试消息,发现 t.start() 被调用,但由于某种原因它什么也没做,也没有抛出异常。每次我再次按下按钮时 LED 不应该开始闪烁吗?

最佳答案

我没有发现任何逻辑故障,并且我确认它有效,但使用了以下更改:

  1. if __name__ == '__main__': 内部启动 main_thread
    我建议也将所有 GPIO 调用移至此 block 内。

避免将启动时执行的代码放在 if __name__ == '__main__':

之外

From the docs: Safe importing of main module One should protect the “entry point” of the program by using if __name__ == '__main__':

  • working = False 之后添加了 join(),这保证了线程在再次启动之前已终止。

    working = False  
    t.join()  
    
  • <小时/>

    我建议将 def flash() 更改为以下内容:
    使用threading.Event()而不是全局实例并将其与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 进行测试

    关于python - 使用多个线程多次调用一个方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42723636/

    相关文章:

    python - C 中的声明考虑了 C++ 中的定义

    python - 使用 Flask,如何修改所有输出的 Cache-Control header ?

    python - 将我的树莓派连接到 MySQL

    python - 树莓派关闭时文件被删除

    python - 使用Python计算云的估计到达时间(ETA)?

    python - Tkinter、变量和函数

    python - 从单个 html 页面上的多个 django 应用程序模型获取数据

    c++ - 究竟什么时候初始化在全局范围内声明的 thread_local 变量?

    c++ - 在没有事件异常的情况下调用线程终止

    asp.net - .Net MVC/Web Api 中的并发请求限制为 10