Linux

在 Linux 中設置管道容量

  • December 6, 2016

有沒有辦法設置在 Bash(或其他 shell)腳本中定義的管道的管道容量?以例如

cmd1 | cmd2

在最近的 Linux 中,管道容量預設設置為 64KB。我知道我可以通過兩種方式控制兩個程序之間“緩衝”的數據量:

  1. 使用buffer(1):例如cmd1 | buffer | cmd2
  2. fcntl(2)從內部使用F_SETPIPE_SZ標誌cmd1cmd2

每種方案都有缺點:buffer只能用來增加緩衝;還寫入預設管道容量仍需要喚醒下游命令。fcntl,據我所知,只能從內部呼叫cmd1or cmd2

我的問題是:有沒有辦法,當外殼創建管道時,在外殼中指定管道應該有多少容量?

根據 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 腳本中指定的容量。

寫入預設管道容量仍需要喚醒下游命令

如果您的目標不是過於頻繁地喚醒下游命令,您是否嘗試過使用-pto 選項buffer?它應該導致buffer保持寫入,直到緩衝區填充到一定百分比。您可能還需要該-s選項來寫入大塊。

更新:D’oh,命令之間的管道仍然限制了事情。也許嘗試使用以下適配器程序:

#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仍然進行少量寫入。

引用自:https://unix.stackexchange.com/questions/328250