在另一个线程中中断 pySerial readline
Posted
技术标签:
【中文标题】在另一个线程中中断 pySerial readline【英文标题】:Interrupt a pySerial readline in another thread 【发布时间】:2021-09-24 15:37:40 【问题描述】:我正在使用 pySerial 通过 USB 与微控制器通信,大部分通信由桌面 python 脚本发起,该脚本发送命令包并等待回复。
但也有可能由微控制器发送的警报数据包,无需来自 python 脚本的命令。在这种情况下,我需要监视读取流中的任何警报。
为了处理警报,我专门使用一个单独的进程来调用readline()
并循环它,如下所示:
def serialMonitor(self):
while not self.stopMonitor:
self.lock.acquire()
message = self.stream.readline()
self.lock.release()
self.callback(message)
在一个类中。然后该函数在一个单独的过程中由
启动self.monitor = multiprocessing.Process(target = SerialManager.serialMonitor, args = [self])
每当发送命令包时,命令函数需要收回对流的控制,为此它必须中断处于阻塞状态的readline()
调用。如何中断readline()
通话?有什么方法可以安全地终止进程吗?
【问题讨论】:
【参考方案1】:您可以使用.terminate()
终止多处理进程。这安全吗?对于 readline 案例来说可能没问题。
但是,这不是我在这里处理事情的方式。当我阅读您的场景时,有两种可能性:
MCU 启动警报包 计算机向 MCU 发送数据(MCU 可能会做出响应)我假设 MCU 在计算机发起交换时不会发送警报包。
所以我会以一个小的超时时间启动串行对象,并在我不使用它时将它留在一个循环中。我的整体流程是这样的:
ser = Serial(PORT, timeout=1)
response = None
command_to_send = None
running = True
while running: # event loop
while running and not command_to_send and not line:
try:
line = ser.readline()
except SerialTimeoutException:
pass
if not command_to_send:
process_mcu_alert(line)
else:
send_command(command_to_send)
command_to_send = None
response = ser.readline()
这只是一个草图,因为它需要在线程或子进程中运行,因为readline()
确实是阻塞的,所以你需要一些线程安全的方法来设置command_to_send
和running
(用于优雅地退出)并获得response
,您可能希望将所有这些状态包装在一个类中。它的精确实现取决于你在做什么,但原理是一样的——有 one 循环来处理串行端口的读写,让它超时以相对快速地响应(你如果需要,可以设置较小的超时时间),并让它公开一些您可以处理的接口。
遗憾的是,据我所知,python 没有兼容 asyncio 的串行库,否则这种方法看起来会更整洁。
【讨论】:
以上是关于在另一个线程中中断 pySerial readline的主要内容,如果未能解决你的问题,请参考以下文章