Linux
在 Linux 中設置管道容量
有沒有辦法設置在 Bash(或其他 shell)腳本中定義的管道的管道容量?以例如
cmd1 | cmd2
在最近的 Linux 中,管道容量預設設置為 64KB。我知道我可以通過兩種方式控制兩個程序之間“緩衝”的數據量:
- 使用
buffer(1)
:例如cmd1 | buffer | cmd2
fcntl(2)
從內部使用F_SETPIPE_SZ
標誌cmd1
或cmd2
每種方案都有缺點:
buffer
只能用來增加緩衝;還寫入預設管道容量仍需要喚醒下游命令。fcntl
,據我所知,只能從內部呼叫cmd1
orcmd2
。我的問題是:有沒有辦法,當外殼創建管道時,在外殼中指定管道應該有多少容量?
根據 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>
並且兩個命令之間的管道將具有通過
fcntl
perl 腳本中指定的容量。
寫入預設管道容量仍需要喚醒下游命令
如果您的目標不是過於頻繁地喚醒下游命令,您是否嘗試過使用
-p
to 選項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
仍然進行少量寫入。