Die Kapazität eines Pipe-Puffers variiert je nach System (und kann sogar auf demselben System variieren). Ich bin nicht sicher, ob es eine schnelle, einfache und plattformübergreifende Möglichkeit gibt, die Kapazität eines Rohrs zu ermitteln.
Mac OS X verwendet beispielsweise standardmäßig eine Kapazität von 16384 Byte, kann jedoch auf 65336 Byte umschalten, wenn große Schreibvorgänge in die Pipe ausgeführt werden, oder auf die Kapazität einer einzelnen Systemseite, wenn bereits zu viel Kernelspeicher vorhanden ist Wird von Pipe-Puffern verwendet (siehe xnu/bsd/sys/pipe.h
und xnu/bsd/kern/sys_pipe.c
; da diese von FreeBSD stammen, kann das gleiche Verhalten auch dort auftreten).
Eine Manpage zu Linux Pipe (7) besagt, dass die Pipe-Kapazität seit Linux 2.6.11 65536 Byte und eine einzelne Systemseite davor beträgt (z. B. 4096 Byte auf (32-Bit) x86-Systemen). Der Code ( include/linux/pipe_fs_i.h
, und fs/pipe.c
) scheint 16 System-Seiten zu verwenden (dh 64 KB, wenn eine System-Seite 4 KB groß ist), aber der Puffer für jede Pipe kann über eine Fcntl in der Pipe angepasst werden (bis zu einer maximalen Kapazität, die standardmäßig 1048576 beträgt) Bytes, kann aber über /proc/sys/fs/pipe-max-size
)) geändert werden .
Hier ist eine kleine Bash / Perl- Kombination, mit der ich die Pipe-Kapazität auf meinem System getestet habe:
#!/bin/bash
test $# -ge 1 || { echo "usage: $0 write-size [wait-time]"; exit 1; }
test $# -ge 2 || set -- "$@" 1
bytes_written=$(
{
exec 3>&1
{
perl -e '
$size = $ARGV[0];
$block = q(a) x $size;
$num_written = 0;
sub report { print STDERR $num_written * $size, qq(\n); }
report; while (defined syswrite STDOUT, $block) {
$num_written++; report;
}
' "$1" 2>&3
} | (sleep "$2"; exec 0<&-);
} | tail -1
)
printf "write size: %10d; bytes successfully before error: %d\n" \
"$1" "$bytes_written"
Ich habe festgestellt, dass es auf einem Mac OS X 10.6.7-System mit verschiedenen Schreibgrößen ausgeführt wird (beachten Sie die Änderung für Schreibvorgänge, die größer als 16 KB sind):
% /bin/bash -c 'for p in {0..18}; do /tmp/ts.sh $((2 ** $p)) 0.5; done'
write size: 1; bytes successfully before error: 16384
write size: 2; bytes successfully before error: 16384
write size: 4; bytes successfully before error: 16384
write size: 8; bytes successfully before error: 16384
write size: 16; bytes successfully before error: 16384
write size: 32; bytes successfully before error: 16384
write size: 64; bytes successfully before error: 16384
write size: 128; bytes successfully before error: 16384
write size: 256; bytes successfully before error: 16384
write size: 512; bytes successfully before error: 16384
write size: 1024; bytes successfully before error: 16384
write size: 2048; bytes successfully before error: 16384
write size: 4096; bytes successfully before error: 16384
write size: 8192; bytes successfully before error: 16384
write size: 16384; bytes successfully before error: 16384
write size: 32768; bytes successfully before error: 65536
write size: 65536; bytes successfully before error: 65536
write size: 131072; bytes successfully before error: 0
write size: 262144; bytes successfully before error: 0
Dasselbe Skript unter Linux 3.19:
/bin/bash -c 'for p in {0..18}; do /tmp/ts.sh $((2 ** $p)) 0.5; done'
write size: 1; bytes successfully before error: 65536
write size: 2; bytes successfully before error: 65536
write size: 4; bytes successfully before error: 65536
write size: 8; bytes successfully before error: 65536
write size: 16; bytes successfully before error: 65536
write size: 32; bytes successfully before error: 65536
write size: 64; bytes successfully before error: 65536
write size: 128; bytes successfully before error: 65536
write size: 256; bytes successfully before error: 65536
write size: 512; bytes successfully before error: 65536
write size: 1024; bytes successfully before error: 65536
write size: 2048; bytes successfully before error: 65536
write size: 4096; bytes successfully before error: 65536
write size: 8192; bytes successfully before error: 65536
write size: 16384; bytes successfully before error: 65536
write size: 32768; bytes successfully before error: 65536
write size: 65536; bytes successfully before error: 65536
write size: 131072; bytes successfully before error: 0
write size: 262144; bytes successfully before error: 0
Hinweis: Der PIPE_BUF
in den C-Header-Dateien definierte Wert (und der Pfadkonfigurationswert für _PC_PIPE_BUF
) gibt nicht die Kapazität der Pipes an, sondern die maximale Anzahl von Bytes, die atomar geschrieben werden können (siehe POSIX- Schreibzugriff (2) ).
Zitat aus include/linux/pipe_fs_i.h
:
/* Differs from PIPE_BUF in that PIPE_SIZE is the length of the actual
memory allocation, whereas PIPE_BUF makes atomicity guarantees. */