readlines must be given a timeout because otherwise it would never finish, since there is no way to detect the end of the serial data stream (EOF).
readline
blocks indefinitely when no data is being sent (or the data doesn't contain a newline), but so does your application. It's perfectly fine to write something like
def read(ser, queue):
while True:
queue.put(ser.readline())
threading.Thread(target=read, args=(ser, queue)).start()
or the more modern equivalent
def read(ser, queue):
for line in ser:
queue.put(line)
threading.Thread(target=read, args=(ser, queue)).start()
However, you should be aware that the reading thread will never finish. So if your program should ever end in a non-exceptional way (i.e. the user can somehow quit it), you need to have a mechanism to signal the reading thread to stop. To make sure that this signal is ever received, you need to use a timeout - otherwise, the thread could block indefinitely in the absence of serial data. For example, this could look like:
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