2016-05-29 2 views
0

Я хотел бы читать из двух (или более) последовательных портов (/ dev/ttyUSB0 и т. Д.) Одновременно в python в Linux. Я хочу читать полные строки из каждого порта (в зависимости от того, какие данные) и обрабатывать результаты в полученном порядке (без условий гонки). В качестве простого примера можно просто написать строки в один объединенный файл.Чтение с двух последовательных портов асинхронно

Я предполагаю, что способ сделать это основан на pyserial, но я не могу понять, как это сделать. Pyserial имеет неблокирующие чтения, используя asyncio и используя threads. Asyncio отмечен как экспериментальный. Я предполагаю, что не будет никаких условий гонки, если обработка будет выполнена в asyncio.Protocol.data_received(). В случае потоков обработка, вероятно, должна быть защищена мьютексом.

Возможно, это также можно сделать не в pyserial. Два последовательных порта можно открыть как файлы, а затем прочитать, когда данные доступны с помощью select().

+2

Сделайте два потока, которые считываются из последовательных портов и помещают данные для обработки в очередь. Посмотрите «производитель-потребитель-питон». –

+0

@AlexHall Звучит как легкое решение проблемы. Отправьте ответ с помощью потоков + queue + pyserial для мгновенного upvote и принимайте :) –

ответ

0

Как пояснил @AlexHall в комментарии, вот решение, которое использует один поток для каждого последовательного порта и очередь для синхронизации доступа:

import serial 
import Queue 
import threading 

queue = Queue.Queue(1000) 

def serial_read(s): 
    while True: 
     line = s.readline() 
     queue.put(line) 

serial0 = serial.Serial('/dev/ttyUSB0') 
serial1 = serial.Serial('/dev/ttyUSB1') 

thread1 = threading.Thread(target=serial_read, args=(serial0,),).start() 
thread2 = threading.Thread(target=serial_read, args=(serial1,),).start() 

while True: 
    line = queue.get(True, 1) 
    print line 

Возможно, это будет возможно более элегантно, но оно будет работать.

0

Вы можете попробовать принимать значения в порядке и запоминать в переменных:

a = data1.read() 
b = data2.read() 

И после того, как процесс его в следующем порядке:

If len (a) != 0 or len (b) != 0: 
      Process a 
      Process b 

Используя этот метод, если один или оба значения имеет данные, обрабатывает их

+0

В первом предлагаемом вами решении data2 может иметь много строк, готовых к чтению, но data1 не имеет ни одного, поэтому первые блоки чтения. Именно этого я и хочу избежать. Во втором решении, использующем потоки, как одна функция обрабатывает строки, которые считываются обоими потоками по порядку и без условий гонки? –

+0

Вам нужно только вставить свой код ... threading - это несколько действий; в то же время. Заметьте, если это сработает. –

+0

Нет, это не сработает. Мне нужно «делать действие», чтобы происходить последовательно, а не в одно и то же время, но с кодом, который у вас есть, это может произойти одновременно. –

Смежные вопросы