시스템 파이프 버퍼 최대값을 늘릴 수 있나요?

시스템 파이프 버퍼 최대값을 늘릴 수 있나요?

약 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(리눅스 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)개방형 파이프에서 시스템 호출을 호출하지 않는 한 기본 용량인 64kB를 유지합니다. 이렇게 하려면 시스템 호출 바인딩을 제공하는 언어(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_SZPerl에 상수 합계 가 없으면 F_SETPIPE_SZC 파일에서 찾은 적절한 숫자를 사용할 수 있습니다 /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;

관련 정보