pyserial - 线程A能写入串口,线程B能阻塞读取吗?

10 投票
3 回答
12460 浏览
提问于 2025-04-17 09:54

我试着在网上搜索这个问题,但没找到答案;在这里也没找到。有没有人研究过从一个线程写入Serial()对象(pyserial)是否是线程安全的,而从另一个线程进行阻塞读取呢?

我知道怎么使用线程同步工具和线程安全的数据结构。其实我现在的程序中有一个专门负责在串口上读写的线程,我也使用线程安全的数据结构来协调应用中的活动。

如果我能从主线程写入串口(而且不读取),并且在第二个线程中使用阻塞读取串口(而且不写入),我的应用会受益匪浅。如果有人真的想知道这样做有什么好处,我可以补充我的理由。在我看来,只有一个Serial()的实例,即使线程B在Serial对象上进行阻塞读取,线程A也可以安全地使用Serial对象的写入方法。

有人知道Serial类可以这样使用吗?

补充:我想到答案可能和平台有关。如果你有在类似平台上的经验,告诉我你使用的是哪个平台会很有帮助。

补充:虽然只有一个回复,但如果其他人也尝试过这个,请分享你的经验。

3 个回答

0

我建议把线程B的“阻塞读取”改成“非阻塞读取/写入”。这样,线程B就可以变成你的串口“守护进程”。

线程A可以全速运行,提供一个友好的用户界面或者执行任何实时操作。

线程A会给线程B发送消息,而不是直接写入串口。如果消息的大小和频率不高,可以用一个简单的共享缓冲区来存放消息,还有一个标志位来表示是否有新消息。如果需要更高的性能,就应该使用栈。其实这可以简单地用一个足够大的数组来实现,存放多个待发送的消息,再加上两个指针。写指针只由线程A更新,读指针只由线程B更新。

线程B会获取消息并将其发送到串口。串口应该使用超时功能,这样读取串口的函数就可以释放CPU,让你去检查共享缓冲区,如果有新消息,就发送到串口。这个时候我会让线程B休眠,以限制它使用的CPU时间。然后,你可以让线程B循环执行读取串口的函数。如果串口的超时功能不正常,比如USB-RS232线被拔掉了,休眠功能就能让你的Python代码表现得更好。

4

我在Linux(还有Windows)上这样使用过pyserial,没遇到任何问题!

15

我用pyserial做过这个。一般来说,从一个线程读取数据,同时在另一个线程写数据是不会出问题的,因为这并不会引起资源争用的问题。串口是全双工的,这意味着读取和写入可以完全独立地同时进行。

撰写回答