在Linux中设置管道容量

在Linux中设置管道容量

有没有办法设置 Bash(或其他 shell)脚本中定义的管道的管道容量?拿例如

cmd1 | cmd2

在最近的 Linux 中,管道容量默认设置为 64KB。我知道我可以通过两种方式控制两个进程之间“缓冲”的数据量:

  1. 使用buffer(1):例如cmd1 | buffer | cmd2
  2. fcntl(2)F_SETPIPE_SZ内部cmd1或内部的标志一起使用cmd2

每种解决方案都有缺点:buffer只能用于增加缓冲区;同样写入默认管道容量仍需要唤醒下游命令。fcntl据我所知,只能从内部调用cmd1cmd2

我的问题是:有没有办法,当外壳创建管道时,在外壳中指定管道应具有多少容量?

答案1

写入默认管道容量仍需要唤醒下游命令

如果您的目标不是太频繁地唤醒下游命令,您是否尝试使用该-p选项buffer?它应该导致buffer保持写入,直到缓冲区被填充到一定百分比。您可能-s还需要该选项来写入大块。

更新:哦,命令之间的管道仍然限制一些事情。也许尝试使用以下适配器程序:

#define _GNU_SOURCE
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
int main(int argc, char** argv)
{
  fcntl(atoi(argv[1]), F_SETPIPE_SZ, atoi(argv[2]));
  execvp(argv[3],argv+3);
  while (1);
}

如:

adapter 1 (BIGSIZE) cmd1 | cmd2

甚至:

adapter 1 (BIGSIZE) cmd1 | adapter 1 (BIGSIZE) buffer [args] | cmd2

如果cmd1仍然进行小写入。

答案2

根据 DepressedDaniel 和 Stéphane Chazelas 的建议,我选择了我能找到的最接近 oneliner 的东西:

function hugepipe {
  perl -MFcntl -e 'fcntl(STDOUT, 1031, 1048576) or die $!; exec { $ARGV[0] } @ARGV or die $!' "$@"
}

这允许执行以下操作:

hugepipe <command> | <command>

两个命令之间的管道将具有通过fcntlperl 脚本中指定的容量。

相关内容