2015-07-09 3 views
0

первый пользователь SO, пожалуйста, извините за любые ошибки этикета. Я пытаюсь реализовать многопоточную программу на python, и у меня проблемы. Это, несомненно, из-за недостаточного понимания того, как выполняется потоковая обработка, но, надеюсь, вы можете помочь мне разобраться в этом.Прослушивание событий по потоку в python

У меня есть базовая программа, которая постоянно прослушивает сообщения на последовательном порту и может затем печатать/сохранять/обрабатывать/и т. Д., Что отлично работает. Это в основном выглядит следующим образом:

import serial 
def main(): 
    usb = serial.Serial('/dev/cu.usbserial-A603UBRB', 57600) #open serial w\ baud rate 
    while True: 
     line = usb.readline() 
     print(line) 

Однако то, что я хочу сделать, это постоянно прослушивать сообщения на последовательный порт, но не обязательно делать что-либо с ними. Это должно выполняться в фоновом режиме, а между тем на переднем плане я хочу иметь какой-то интерфейс, где пользователь может заставить программу читать/использовать/сохранять эти данные некоторое время, а затем останавливаться снова.

Таким образом, я создал следующий код:

import time 
import serial 
import threading 

# this runs in the background constantly, reading the serial bus input 
class serial_listener(threading.Thread): 
    def __init__(self, line, event): 
     super(serial_listener, self).__init__() 
     self.event = threading.Event() 
     self.line = '' 
     self.usb = serial.Serial('/dev/cu.usbserial-A603UBRB', 57600) 

    def run(self): 
     while True: 
      self.line = self.usb.readline() 
      self.event.set() 
      self.event.clear() 
      time.sleep(0.01) 

# this lets the user command the software to record several values from serial 
class record_data(threading.Thread): 
    def __init__(self): 
     super(record_data, self).__init__() 
     self.line = '' 
     self.event = threading.Event() 
     self.ser = serial_listener(self.line,self.event) 
     self.ser.start() #run thread 

    def run(self): 
     while(True): 
      user_input = raw_input('Record data: ') 
      if user_input == 'r': 
       event_counter = 0 
       while(event_counter < 16): 
        self.event.wait() 
        print(self.line) 
        event_counter += 1 

# this is going to be the mother function 
def main(): 
    dat = record_data() 
    dat.start() 

# this makes the code behave like C code.  
if __name__ == '__main__': 
    main()  

Он собирает и работает, но когда я заказываю программу для записи, набрав г в CLI, ничего не происходит. Кажется, он не получает никаких событий.

Любые подсказки, как сделать эту работу? Обходные решения также прекрасны, единственное, что я не могу постоянно открывать и закрывать последовательный интерфейс, он должен оставаться открытым все время, иначе устройство перестает работать до un/replugged.

ответ

1

Вместо использования нескольких потоков я бы предложил использовать несколько процессов. Когда вы используете потоки, вам нужно подумать о блокировке глобального интерпретатора. Таким образом, вы либо слушаете события, либо делаете что-то в своей основной теме. Оба в то же время не будут работать.

При использовании нескольких процессов я бы использовал очередь для пересылки событий из вашего сторожевого таймера, с которым вы бы хотели справиться. Или вы можете закодировать собственный обработчик событий. Here вы можете найти пример для обработчиков событий многопроцессора

+0

Спасибо за совет. В то время я не мог понять, и в итоге приступил к простому созданию двух отдельных сценариев python, которые обмениваются данными через кеш на диске. Через несколько месяцев я вернулся к этой проблеме и решил перестроить мой графический интерфейс в pyqt вместо tkinter. И с классом QThread от PyQT мне стало очень легко делать то, что я хотел, намного проще, чем с модулем потоковой передачи. – James

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