为什么我要在Python中运行一个额外的线程?

约翰

我正在使用Raspberry Pi。

我有一个按钮连接到GPIO引脚,一个LED连接到另一个引脚。当按下按钮时,将调用一个功能。该功能处于活动状态时,我希望LED闪烁,这需要后台线程。本质上,这意味着我需要一个后台线程在我的按钮处理程序运行时运行,并在我的按钮处理程序停止时停止。

通过运行以下代码可以证明我遇到的问题。该代码从一个线程开始,但是当我按下按钮时,threading.active_count()显示正在运行3个线程(而不是预期的2个)。当我的线程运行完毕后,剩下2个后台线程-而不是预期的1个。

这是我的代码:

#!/usr/bin/env python3

import RPi.GPIO as GPIO
import time
import threading
from threading import Thread, Event

#########################
# Function to Blink LED #
#########################

# Sample function that blinks the LED
def blink_led_func(led, stop_blinking):
    while not stop_blinking.is_set():
        print("Blinking LED...")
        time.sleep(0.5)

#############
# Decorator #
#############

# Starts a background thread which blinks the LED, runs the decorated
# function, and when the function is done running, stops blinking the LED
class blink_led:
    def __init__(self, function):
        self.f = function

    def __call__(self, channel):
        stop = Event()
        t = Thread(target=blink_led_func, args=(1, stop))
        t.start()

        self.f(channel)

        stop.set()
        t.join()

##################
# Button Handler #
##################

# Called when button is pressed
@blink_led
def btn_handler(channel):
    print("Button pressed")
    time.sleep(5)

##############
# Setup GPIO #
##############

# Setup pin
GPIO.setmode(GPIO.BOARD)
GPIO.setup(12, GPIO.IN, pull_up_down=GPIO.PUD_UP)

##############################
# Add Button Event Listeners #
##############################

GPIO.add_event_detect(12, GPIO.FALLING, callback=btn_handler, bouncetime=300)

########
# Main #
########

print("Listening for button presses...")

i = 0
while True:
    time.sleep(1)
    print("%s threads running" % threading.active_count())

这是我的代码的输出:

Listening for button presses...
1 threads running
1 threads running
1 threads running
Blinking LED...
Button pressed
3 threads running
Blinking LED...
Blinking LED...
3 threads running
Blinking LED...
Blinking LED...
3 threads running
Blinking LED...
Blinking LED...
3 threads running
Blinking LED...
Blinking LED...
3 threads running
Blinking LED...
Blinking LED...
Button pressed
3 threads running
Blinking LED...
Blinking LED...
3 threads running
Blinking LED...
Blinking LED...
3 threads running
Blinking LED...
Blinking LED...
3 threads running
Blinking LED...
Blinking LED...
3 threads running
Blinking LED...
2 threads running
2 threads running
2 threads running

这让我不寒而栗,因为在我的真实代码中,我有一个Ctrl + C处理程序,该处理程序说:使用threading.Event()发出所有线程死亡的信号,等待active_count() == 1(仅剩下主线程),清理GPIO,然后出口。从理论上讲,这应该可以防止后台线程尝试在清除后使用GPIO库闪烁(这将导致异常),但实际上,它会卡在等待其他线程消失的状态,因为总有2个由于某些原因。

我做错什么了吗?还是GPIO库做一些时髦的事情?

编辑:如果我注释掉该GPIO.add_event_detect行,并向btn_handler函数添加手动调用,而不是(btn_handler(1)),则不会出现此问题。函数运行完后,根据,我只有1个线程active_count()无论问题是什么,似乎都与我在GPIO事件处理函数中启动线程有关。

还要注意,如果我没有在btn_handler中启动后台线程,则active_count()在整个运行过程中都保持为1,据我所知,GPIO库未在运行任何后台线程。

编辑2:还请注意,当我只有2个正在运行的线程(当我只希望有一个)时,如果我添加代码以检查线程的名称,则多余的线程称为“ Dummy-3”

暗影游侠

RPi.GPIO的事件处理在隐式启动的专用线程中执行,以处理执行的回调:

RPi.GPIO运行第二个用于回调函数的线程。这意味着回调函数可以与主程序同时运行,以立即响应边缘。

无论注册了多少个回调,这些线程中只有一个:

回调函数按顺序运行,而不是同时运行。这是因为只有一个线程用于回调,每个线程都按照其定义的顺序运行。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

为什么我的for循环在R中运行一个额外的迭代?

来自分类Dev

graphql 为什么我需要在解析器参数中声明一个额外的参数

来自分类Dev

为什么我会收到一个功能错误,说我需要在我的 python 代码中添加一个功能?

来自分类Dev

为什么它给了我一个额外的词?

来自分类Java

信号量-为什么我的线程一个接一个地运行,而不是并发运行?

来自分类Linux

为什么要在POSIX sh的`test` /`[`字符串比较中附加一个额外的字符?

来自分类Dev

为什么我在 Python 中的递归骑士代码只运行第一个堆栈?

来自分类Dev

为什么这会不断在我的计数中添加一个额外的 1?

来自分类Linux

为什么Seaborn在我的数据中创建一个额外的类别?

来自分类Dev

为什么我在 React Native 中的放大联合登录会添加一个额外的“https”?

来自分类Dev

为什么在我的Linux内核中的/ dev下添加了一个额外的HDD?

来自分类Dev

我想每x秒在一个线程python中运行一个函数

来自分类Dev

为什么我需要在数组中附加一个 NUL 字符?

来自分类Dev

为什么我们需要在React Hook中返回一个函数?

来自分类Dev

为什么我们需要在堆中创建一个对象?

来自分类Dev

为什么会有一个额外的&来将非静态成员函数的地址传递给C ++中的线程?

来自分类Dev

为什么我们需要在运行时实例化一个类型?

来自分类Dev

为什么我得到一个线程而不是参数?

来自分类Dev

我们真的需要在Johnson算法中添加一个额外的节点吗?

来自分类Java

为什么我会放置一个synchronized块单线程方法中?

来自分类Dev

为什么我的回调消息在另一个线程中执行?

来自分类Dev

线程化,以及为什么我的程序似乎卡在一个方法中

来自分类Dev

我的程序不会输出我输入要在数组中搜索的第一个值。为什么?

来自分类Dev

为什么我不告诉我,Python Threading会运行一个函数?

来自分类Dev

为什么要在Python中获得额外的条形图?

来自分类Python

我可以在一个heroku(python)dyno中运行多个线程吗?

来自分类Java

为什么要在另一个列表中投射一个列表

来自分类Dev

为什么我的循环在我的 YAML 文件末尾添加了一个额外的键值对?

来自分类Dev

为什么我们需要在优先级队列声明中添加一个向量作为参数?

Related 相关文章

  1. 1

    为什么我的for循环在R中运行一个额外的迭代?

  2. 2

    graphql 为什么我需要在解析器参数中声明一个额外的参数

  3. 3

    为什么我会收到一个功能错误,说我需要在我的 python 代码中添加一个功能?

  4. 4

    为什么它给了我一个额外的词?

  5. 5

    信号量-为什么我的线程一个接一个地运行,而不是并发运行?

  6. 6

    为什么要在POSIX sh的`test` /`[`字符串比较中附加一个额外的字符?

  7. 7

    为什么我在 Python 中的递归骑士代码只运行第一个堆栈?

  8. 8

    为什么这会不断在我的计数中添加一个额外的 1?

  9. 9

    为什么Seaborn在我的数据中创建一个额外的类别?

  10. 10

    为什么我在 React Native 中的放大联合登录会添加一个额外的“https”?

  11. 11

    为什么在我的Linux内核中的/ dev下添加了一个额外的HDD?

  12. 12

    我想每x秒在一个线程python中运行一个函数

  13. 13

    为什么我需要在数组中附加一个 NUL 字符?

  14. 14

    为什么我们需要在React Hook中返回一个函数?

  15. 15

    为什么我们需要在堆中创建一个对象?

  16. 16

    为什么会有一个额外的&来将非静态成员函数的地址传递给C ++中的线程?

  17. 17

    为什么我们需要在运行时实例化一个类型?

  18. 18

    为什么我得到一个线程而不是参数?

  19. 19

    我们真的需要在Johnson算法中添加一个额外的节点吗?

  20. 20

    为什么我会放置一个synchronized块单线程方法中?

  21. 21

    为什么我的回调消息在另一个线程中执行?

  22. 22

    线程化,以及为什么我的程序似乎卡在一个方法中

  23. 23

    我的程序不会输出我输入要在数组中搜索的第一个值。为什么?

  24. 24

    为什么我不告诉我,Python Threading会运行一个函数?

  25. 25

    为什么要在Python中获得额外的条形图?

  26. 26

    我可以在一个heroku(python)dyno中运行多个线程吗?

  27. 27

    为什么要在另一个列表中投射一个列表

  28. 28

    为什么我的循环在我的 YAML 文件末尾添加了一个额外的键值对?

  29. 29

    为什么我们需要在优先级队列声明中添加一个向量作为参数?

热门标签

归档