在文档中混淆“readline”警告

时间:2013-09-11 11:14:39

标签: python pyserial

我正在尝试按照this advice实现串行通信。

基本上我会有一个单独的线程,阻塞,监听端口,当收到完整的一行时,将其推送到全局队列。

但是,文档中的这个警告让我感到困惑:

  

readlines() only works with a timeout

这是什么意思?我如何实现我的意图。我讨厌必须

while True:
    a = self.ser.read(1)
    if a == '/n':
        blqblq()
    elif a == '/r'
        b = self.ser.read(1)
        if b == '/n':
            nana()

1 个答案:

答案 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