在Tornado中没有收到所有命名管道输出

时间:2015-04-20 15:00:45

标签: python linux asynchronous tornado fifo

我正在使用Tornado运行一个小型python程序,它收集了由另一个程序编写的多个linux命名管道(FIFO)输出。不幸的是,并非由于某种原因收到管道的所有输出。

我像这样添加管道:

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运行程序(也以相同的方式捕获它的stdout / err)并在子进程结束时退出。

我没有收到所有预期的输出(例如,我将在程序中打印10000行,但在python程序中只接收~7000)。当我只是用“cat”来获得fifo输出时,我可以看到它。

我确保程序正确刷新输出。我试着在程序中永远睡觉,让Tornado有时间获得输出,但结果却相同。

有什么想法吗?

2 个答案:

答案 0 :(得分:0)

当缓冲区中仍有数据时,

stream.closed()可能会变为真。为确保您已阅读所有内容,请使用set_close_callback()并阅读,直到运行回调,或使用协程式界面并阅读,直到您收到StreamClosedError。

一般情况下,写作时应使用stream.closed(),因此您不要尝试写入不再存在的客户端,但阅读关闭回调更合适。

答案 1 :(得分:0)

通过更改C程序中管道的打开来解决问题:

open(fifo_path, O_WRONLY | O_NONBLOCK);

要:

open(fifo_path, O_RDWR);

请参阅these questions