如何(我可以)询问PIPE有多少字节可供阅读?

Mat*_*att 6 python subprocess popen nonblocking

我在Python中实现了一个非阻塞读取器,我需要提高它的效率.

背景:我需要从一个子进程(从Popen()开始)读取大量输出并传递给另一个线程.读取该子进程的输出不得阻塞超过几毫秒(最好是读取可用字节所需的时间很短).

目前,我有一个实用程序类,它接受文件描述符(stdout)和超时.我select()readline(1)直到三件事情之一碰巧:

  1. 我读了一个换行符
  2. 我的超时(几毫秒)到期
  3. select告诉我那个文件描述符没什么可读的.

然后我将缓冲的文本返回给调用方法,该方法用它来完成.

现在,对于真正的问题:因为我正在阅读如此多的输出,我需要提高效率.我想通过询问文件描述符有多少字节待处理来做到这一点readline([that many bytes]).它应该只是传递东西,所以我实际上并不关心新线,或者即使有任何.我可以问一下文件描述符可以读取多少字节,如果可以,怎么做?

我已经做了一些搜索,但是我很难找到要搜索的内容,更不用说是否可能了.

即使是正确方向的一点也会有所帮助.

注意:我正在开发Linux,但这对于"Pythonic"解决方案来说无关紧要.

Rol*_*ith 5

在Linux上,os.pipe()它只是管道(2)的包装器.两者都返回一对文件描述符.通常会使用lseek(2)(os.lseek()在Python中)重新定位文件decsriptor的偏移量,作为获取可用数据量的方法.但是,并非所有文件描述符都能够搜索.

在Linux上尝试管道上的lseek(2)将返回错误,请参阅手册页.这是因为管道或多或少是生产者和数据消费者之间的缓冲区.该缓冲区的大小取决于系统.

在Linux上,管道具有64 kB缓冲区,因此这是您可以获得的最多数据.

编辑:如果您可以更改子进程的工作方式,您可以考虑使用内存映射文件或一个很好的大块共享内存.

Edit2:使用轮询对象可能比select更快.