如何在 Python 代码继续 运行 时连续闪烁 LED(或其他 while 循环)

How to continuously flash LED (or other while loop) while Python code continues to run

我希望能够在主 while 循环继续时让 LED 持续闪烁。我知道在下面的代码中,当函数 led_flash() 被调用时,脚本将停止,直到函数中定义的 while 循环结束。这禁止来自 运行 的剩余代码。

import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)
GPIO.setup(25, GPIO.OUT)

def led_flash():
    while TRUE:
        GPIO.output(25, ON)
        time.sleep(1)
        GPIO.output(25, OFF)
        time.sleep(1)

while True:
    if x=1
        led_flash()
        ...do other stuff

我已经读到线程将在这种情况下工作,但是我还没有找到足够简单的例子让我掌握。此外,如果线程化,我将如何在主 while 循环中结束 led_flash() 函数线程?

根据 here and here 的回答,您可以像这样开始一个话题:

import threading
while True:
    if x = 1:
        flashing_thread = threading.Thread(target=led_flash)
        flashing_thread.start()
        #continue doing stuff

因为,在你的情况下,你想停止线程(我假设如果 x 不等于 1),那么你可以创建一个停止 class 的线程所以:

import threading
import sys

class StopThread(StopIteration): pass

threading.SystemExit = SystemExit, StopThread

class Thread2(threading.Thread):

    def stop(self):
        self.__stop = True

    def _bootstrap(self):
        if threading._trace_hook is not None:
            raise ValueError('Cannot run thread with tracing!')
        self.__stop = False
        sys.settrace(self.__trace)
        super()._bootstrap()

    def __trace(self, frame, event, arg):
        if self.__stop:
            raise StopThread()
        return self.__trace

并这样称呼它:flashing_thread.stop()

把它们放在一起得到:

import threading
import sys
import RPi.GPIO as GPIO
import time

class StopThread(StopIteration): pass

threading.SystemExit = SystemExit, StopThread

class Thread2(threading.Thread):

    def stop(self):
        self.__stop = True

    def _bootstrap(self):
        if threading._trace_hook is not None:
            raise ValueError('Cannot run thread with tracing!')
        self.__stop = False
        sys.settrace(self.__trace)
        super()._bootstrap()

    def __trace(self, frame, event, arg):
        if self.__stop:
            raise StopThread()
        return self.__trace
#############################################################

GPIO.setmode(GPIO.BCM)
GPIO.setup(25, GPIO.OUT)

def led_flash():
    while TRUE:
        GPIO.output(25, ON)
        time.sleep(1)
        GPIO.output(25, OFF)
        time.sleep(1)

# x gets defined somewhere

while True:
    if x == 1:
        flashing_thread = Thread2(target=led_flash)
        flashing_thread.start()
        #continue doing stuff
    else:
        if flashing_thread and flashing_thread.isAlive():
            flashing_thread.stop()

看文档后的一个简单例子:

from threading import Thread
import time

def main_loop():
    mythread = LedThread()
    mythread.start()

    time.sleep(20) # execute while loop for 20 seconds
    mythread.stop()

class LedThread(Thread):

    def __init__(self):
        super(LedThread, self).__init__()
        self._keepgoing = True

    def run(self):
        while (self._keepgoing):
            print 'Blink'
            time.sleep(0.5)


    def stop(self):
        self._keepgoing = False

main_loop()

理想情况下,您应该使用 threading.Thread.__init__ 中的 target 参数,因为它允许您将函数推送到线程中。 Ryan Schuster 的示例是两者中更强大的一个,不过我希望这个示例可以帮助您理解什么是线程,只使用 运行 一个所必需的基础知识。