2015-04-20 24 views
1

我正在运行一个使用Tornado的小型python程序,该程序收集由另一个程序写入的多个linux命名管道(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) 

我终于有龙卷风的子流程运行的程序(也捕获标准输出/ ERR在同样的方式),并在子进程结束时退出。

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

我确保程序正确刷新输出。我试着在程序中永久睡眠,以允许Tornado获得输出,但它有相同的结果。

任何想法?

+0

我为我的C程序添加了10秒的睡眠和刷新,并且数据仍然没有通过龙卷风管道接收(尽管我看到了stdout)。 – KimiNewt

回答

0

stream.closed()可能在缓冲区中仍有数据时变为真。为确保您已阅读所有内容,请使用set_close_callback()并阅读,直到该回调运行,或者使用协程式接口并读取,直到出现StreamClosedError。

一般来说,写作时应该使用stream.closed(),所以您不要尝试写入不再存在的客户端,而是用于读取关闭回调更合适。

+0

等待StreamClosedError似乎不起作用(仍然使用回调)。我得到了错误,但数据仍然没有写入。 – KimiNewt

0

问题解决了通过改变管道的开放在我的C程序:

open(fifo_path, O_WRONLY | O_NONBLOCK); 

要:

open(fifo_path, O_RDWR); 

thesequestions