我正在为树莓派开发一个小型Python程序,用于侦听Zigbee网络上的一些事件。
我写这个的方式相当简单,我有一个时间(True):循环检查来自Zigbee的唯一ID (UID)。如果接收到UID,它将被发送到包含一些回调方法的字典。因此,例如,在字典中,键101绑定到一个名为PrintHello()的方法。
如果key/UID被接收,PrintHello方法将被执行-非常简单,像这样:
if self.expectedCallBacks.has_key(UID) == True:
self.expectedCallBacks[UID]()
我知道这种方法可能过于简单。我主要关心的是,如果系统正忙于处理一个方法,而系统又接收到另一条消息,该怎么办?
在嵌入式MCU上,我可以很容易地处理循环器缓冲区+中断,但我有点迷失了与RPi一起做这件事。我是否需要为Zigbee模块实现一个新线程,该线程基本上填充了回调处理程序可以检索/读取的缓冲区?
线程在这里一定程度上可以提供帮助。下面是一个使用ThreadPool
的简单示例:
from multiprocessing.pool import ThreadPool
pool = ThreadPool(2) # Create a 2-thread pool
while True:
uid = zigbee.get_uid()
if uid in self.expectedCallbacks:
pool.apply_async(self.expectedCallbacks[UID])
将在线程池中的线程中启动回调,并且应该有助于防止在将事件发送给回调处理程序之前备份事件。当池中的所有线程都在工作时,ThreadPool
将在内部处理无法运行的任务队列。
然而,请记住树莓派只有一个CPU核心,所以你不能同时执行多个基于CPU的操作(这甚至忽略了Python中由GIL引起的线程限制,这通常通过使用多个进程而不是线程来解决)。这意味着无论您有多少线程/进程,一次只有一个线程/进程可以访问CPU。出于这个原因,您可能不希望实际运行回调的线程多于一个,因为随着您添加更多的线程,您只会减慢速度,因为操作系统需要不断地在线程之间切换。