2015-04-20 3 views
1

Я запускаю небольшую программу python с использованием Tornado, которая собирает выходы нескольких именованных каналов (FIFO), написанные другой программой. К сожалению, не все выходные данные из труб получены по какой-то причине.Не получать все именованные выходные данные в Tornado

добавить трубы так:

for pipe in pipe_files: 
    pipe_file = open(pipe, 'r') 
    try: 
     pipe_stream = PipeIOStream(pipe_file.fileno()) 
     self.output_streams.append(pipe_stream) 
    except IOError: 
     logging.warn("Can't open pipe %s", pipe) 
     continue 
    self.read_lines(pipe_stream, self.new_output) 

прочитанной строки регистрирует функцию обратного вызова следующим образом:

def read_lines(self, stream, callback): 
    """ 
    Read lines forever from the given stream, calling the callback on each line. 

    :param stream: a tornado.BaseIOStream 
    :param callback: callback method to be called for each line. 
    """ 
    def wrapper(line): 
     if not self.output_streams: 
      # Output streams have been removed, no need to continue. 
      return 

     callback(line.strip()) 
     # Reregister the callback, if the stream hasn't closed yet. 
     if not stream.closed(): 
      stream.read_until(os.linesep, callback=wrapper) 
    stream.read_until(os.linesep, callback=wrapper) 

Я, наконец, запустить программу с Subprocess смерча (также захватив ее стандартный вывод/ERR в таким же образом) и выход, когда заканчивается подпроцесс.

Я не получаю весь ожидаемый результат (например, я буду печатать 10000 строк в программе, но только получаю ~ 7000 в программе python). Когда я просто использовал «cat», чтобы получить выход fifo, я мог видеть это.

Я гарантировал, что программа корректно выдает выход. Я пробовал спать вечно в программе, чтобы позволить Торнадо некоторое время получить выход, но он имел тот же результат.

Любые идеи?

+0

Я добавил 10 секунд сна и флеш к моей программе на C, и данные по-прежнему не были получены через трубы в торнадо (я все же видел stdout). – KimiNewt

ответ

0

stream.closed() может стать истинным, пока в буферах все еще есть данные. Чтобы убедиться, что вы все прочитали, используйте set_close_callback() и прочитайте до тех пор, пока этот обратный вызов не будет запущен, или используйте интерфейс в стиле coroutine и не прочитайте, пока не получите StreamClosedError.

В общем, stream.closed() следует использовать при записи, поэтому вы не пытаетесь писать клиенту, которого больше нет, но для более точного чтения обратного вызова.

+0

Ожидание StreamClosedError не работает (по-прежнему использует обратные вызовы). Я получаю ошибки, но данные еще не написаны. – KimiNewt

0

Проблема была решена путем изменения открытия труб в моей программе C от:

open(fifo_path, O_WRONLY | O_NONBLOCK); 

Кому:

open(fifo_path, O_RDWR); 

См thesequestions.

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