約5MBのバッファを持つFIFOパイプを作成したいと思います。 LinuxのデフォルトのFIFOパイプバッファの最大値は約1MBであることがわかります。 /proc/sys/fs/pipe-max-sizeにあることを確認しました。
私は次のように設定してみました。
sudo sysctl fs.pipe-max-size=4194304
次に、値が実際に変更されたことを確認します。
$ cat /proc/sys/fs/pipe-max-size
4194304
その後、新しいFIFOパイプを作成しましたが、パフォーマンスが向上することを感じませんでした。以前の1MBのFIFOパイプと同じ速度で満たされているようです。だから私の新しいFIFOパイプに実際に4MBのバッファがあるかどうかはわかりません。
1)システムFIFOパイプバッファの最大値を増やし、2)このバッファ最大値を使用するFIFOパイプを作成するにはどうすればよいですか?
答え1
コマンドは、デフォルトのバッファサイズではなく最大バッファサイズを変更します。
~からPipe(7) マンページ:
/proc/sys/fs/pipe-max-size
(Linux 2.6.35以降)CAP_SYS_RESOURCE機能を持たないユーザーが単一のパイプに対して設定できる最大サイズ(バイト単位)。
そして:
Linux 2.6.11以降、パイプ容量は16ページです(つまり、ページサイズが4096バイトのシステムでは65,536バイト)。 Linux 2.6.35以降、デフォルトのパイプ容量は16ページですが、
fcntl
(2)とF_GETPIPE_SZ
操作を使用してF_SETPIPE_SZ
容量を照会して設定できます。
したがって、fcntl(F_SETPIPE_SZ)
オープンパイプでシステムコールを呼び出さない限り、基本容量である64 kBを維持します。これを行うには、システムコールバインディングを提供する言語(C / C ++、Python、PHP、perl ...ただsh / bashを除く)を使用する必要があります。
答え2
xhienneの答えに基づいて、このPerlスクリプトは既存のオープンFIFOのサイズを設定します。
#!/usr/bin/perl
# usage: name-of-open-fifo size-in-bytes
# http://unix.stackexchange.com/a/353761/119298
use strict;
use Fcntl;
my $fifo = shift @ARGV or die "usage: fifo size";
my $size = shift @ARGV or die "usage: fifo size";
open(FD, $fifo) or die "cannot open";
printf "old size %d\n",fcntl(\*FD, Fcntl::F_GETPIPE_SZ, 0);
my $new = fcntl(\*FD, Fcntl::F_SETPIPE_SZ, int($size));
die "failed" if $new<$size;
printf "new size %d\n",$new;
たとえば、ファイルに入れて操作を~/setfifo
実行chmod +x
し、FIFO を作成して開き、実行します。例:
$ mkfifo /tmp/fifo
$ cat -n <>/tmp/fifo &
$ ~/setfifo /tmp/fifo 1048576
old size 65536
new size 1048576
F_GETPIPE_SZ
Perlに定数の合計がない場合は、F_SETPIPE_SZ
Cファイルで見つかった適切な数値を使用できます/usr/include/
。それぞれ1024+8と1024+7です。生成されたPerlスクリプトは次のとおりです。
#!/usr/bin/perl
# usage: name-of-open-fifo size-in-bytes
# http://unix.stackexchange.com/a/353761/119298
use strict;
# int fcntl(int fd, int cmd, ...) F_GETPIPE_SZ,void F_SETPIPE_SZ,int
# /usr/include/asm-generic/fcntl.h #define F_LINUX_SPECIFIC_BASE 1024
# /usr/include/linux/fcntl.h #define F_SETPIPE_SZ (F_LINUX_SPECIFIC_BASE + 7)
sub F_SETPIPE_SZ{ 1024+7; }
sub F_GETPIPE_SZ{ 1024+8; }
my $fifo = shift @ARGV or die "usage: fifo size";
my $size = shift @ARGV or die "usage: fifo size";
open(FD, $fifo) or die "cannot open";
printf "old size %d\n",fcntl(\*FD, F_GETPIPE_SZ, 0);
my $new = fcntl(\*FD, F_SETPIPE_SZ, int($size));
die "failed" if $new<$size;
printf "new size %d\n",$new;