Pipe

確定生產者是否在管道中超過消費者

  • April 27, 2018

如果我有:

node foo.js | node bar.js

有沒有辦法確定他們之間是否有一個正在建立的隊列?換句話說,如果生產者的速度超過了消費者的標準輸出?

您可以ioctl(,FIONREAD,)在 Linux 中使用管道來獲取目前可讀取的字節數。這可能在man 7 pipe(FIONREAD也在man tty_ioctl) 中找到。您可以將其集成到您的應用程序中,也可以使用管道作為標準輸入並行執行類似 perl 的東西:

#!/usr/bin/perl
# https://unix.stackexchange.com/a/440361/119298
use strict;
require 'sys/ioctl.ph';
my $v = pack("l",0);
$| = 1;
# while(1)
{
 die "ioctl: $!" if ioctl(STDIN, &FIONREAD, $v)!=0;
 my @r = unpack("l",$v);
 printf "%d ",$r[0];
#  sleep 1;
}

所以用法是

node foo.js | (myperl & node bar.js)

嘗試一下

while sleep 1;do date;done |
while sleep 1.1;do myperl 2>/dev/null; dd status=none count=1 bs=20;done

我從perlabout收到警告_FORTIFY_SOURCE,因此是 stderr 重定向。dd讀數小於長度,因此date您可以看到結果逐漸增加。

為了完整起見,您可以獲取管道的容量fcntl(,F_GETPIPE_SZ)並將其設置為fcntl(,F_SETPIPE_SZ,newvalue)up /proc/sys/fs/pipe-max-size(除非 root 或 have CAP_SYS_RESOURCE)。見man fcntl

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