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

时间:2016-04-06 17:22:40

标签: python raspberry-pi python-multithreading gpio

我希望能够在我的主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

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

2 个答案:

答案 0 :(得分:3)

根据herehere的答案,您可以开始这样的话:

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

因为,在你的情况下,你想要停止线程(假设x不等于1),那么你可以像这样创建一个线程停止类:

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

答案 1 :(得分:1)

查看文档后的一个简单示例:

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

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