我正在尝试按照this advice实现串行通信。
基本上我会有一个单独的线程,阻塞,监听端口,当收到完整的一行时,将其推送到全局队列。
但是,文档中的这个警告让我感到困惑:
这是什么意思?我如何实现我的意图。我讨厌必须
while True:
a = self.ser.read(1)
if a == '/n':
blqblq()
elif a == '/r'
b = self.ser.read(1)
if b == '/n':
nana()
答案 0 :(得分:4)
readline s 必须超时,否则它永远不会完成,因为无法检测到串行数据流(EOF)的结束。
当没有数据发送时(或数据不包含换行符), readline
无限期地阻塞,但您的应用程序也是如此。写一些像
def read(ser, queue):
while True:
queue.put(ser.readline())
threading.Thread(target=read, args=(ser, queue)).start()
或更现代的等价物
def read(ser, queue):
for line in ser:
queue.put(line)
threading.Thread(target=read, args=(ser, queue)).start()
但是,您应该知道阅读主题永远不会完成。所以如果你的程序应该以非特殊方式结束(即用户可以某种方式退出它),你需要有一种机制来通知读取线程停止。为了确保收到此信号,您需要使用超时 - 否则,在没有串行数据的情况下,线程可能无限期地阻塞。例如,这可能看起来像:
def read(ser, queue):
buf = b''
ser.timeout = 1 # 1 second. Modify according to latency requirements
while not should_stop.is_set():
buf += ser.readline()
if buf.endswith('\n'):
queue.put(line)
buf = b''
# else: Interrupted by timeout
should_stop = threading.Event()
threading.Thread(target=read, args=(ser, queue)).start()
# ... somewhat later
should_stop.set() # Reading thread will exit within the next second