我在Raspberry Pi板上使用Python与Rasbian操作系统(基于Linux)。我的Python脚本使用GPIO(硬件输入)。我注意到当GPIO激活时,它的回调会中断当前线程。强制Python在单线程中运行
这迫使我使用锁来防止线程访问公共资源时出现问题。然而它变得有点复杂。让我感到吃惊的是,如果GPIO“排队”直到主线程进入睡眠状态(例如命中time.sleep
),它将大大简化事情(即像JavaScript处理事物的方式)。
有没有办法在Python中实现这个?
我在Raspberry Pi板上使用Python与Rasbian操作系统(基于Linux)。我的Python脚本使用GPIO(硬件输入)。我注意到当GPIO激活时,它的回调会中断当前线程。强制Python在单线程中运行
这迫使我使用锁来防止线程访问公共资源时出现问题。然而它变得有点复杂。让我感到吃惊的是,如果GPIO“排队”直到主线程进入睡眠状态(例如命中time.sleep
),它将大大简化事情(即像JavaScript处理事物的方式)。
有没有办法在Python中实现这个?
你使用的是RPi.GPIO library
?或者在回调触发时从C调用你的Python代码?
如果是RPi.GPIO
,它将运行一个有效的Python线程,如果您正确组织线程交互,则不需要额外的同步。
最常见的模式是将你的事件放入队列中(在Python 3的情况下,this library可以完成这项工作,Python 2的作用是this one)。然后,当主线程准备好处理事件时,处理队列中的所有事件。唯一的问题是你如何找到处理它们的时刻。最简单的解决方案是实现一个可以随时调用它的函数。如果使用长号码sleep
,则可能必须将其分成许多较小的睡眠区域,以确保外部事件经常处理得足够频繁。您甚至可以为sleep
实施自己的包装,将一个较大的延迟拆分为几个较小的延迟,并处理它们之间的队列。另一种解决方案是使用Queue.get
和timeout
参数,而不是sleep
(它在事件到达队列后立即返回),但是,如果您需要准确睡眠一段时间,您可能需要执行一些额外的魔术,例如如果您需要在处理事件后等待更多时间,请自己测量时间并再次致电get
。
使用多线程模块中的队列来存储要执行的任务。主循环会定期检查队列中的条目,并在发现某些内容时逐个执行它们。
您的GPIO监控线程将他们的任务放入队列中(只有一个需要从多个线程收集)。
您可以将任务建模为可调用对象或函数对象。