Als Kommentar in bin ich verwirrt, warum „| true“ in einem Makefile hat denselben Effekt wie „|| wahr“ Benutzer cjm schrieb:
Ein weiterer Grund, | true
ist, dass, wenn der Befehl genug Ausgabe erzeugt, um den Pipe-Puffer zu füllen, er das Warten auf true blockieren würde, um ihn zu lesen.
Können wir irgendwie herausfinden, wie groß der Pipe-Puffer ist?
Akzeptierte Antwort:
Die Kapazität eines Pipe-Puffers variiert zwischen den Systemen (und kann sogar auf demselben System variieren). Ich bin mir nicht sicher, ob es eine schnelle, einfache und plattformübergreifende Möglichkeit gibt, einfach die Kapazität einer Pipe nachzuschlagen.
Mac OS X verwendet beispielsweise standardmäßig eine Kapazität von 16384 Byte, kann jedoch auf 65336 Byte Kapazität umschalten, wenn große Schreibvorgänge in die Pipe vorgenommen werden, oder auf eine Kapazität von einer einzelnen Systemseite umschalten, wenn bereits zu viel Kernelspeicher vorhanden ist von Pipe-Puffer verwendet wird (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 Linux-pipe(7) Manpage sagt, dass die Pipe-Kapazität 65536 Bytes seit Linux 2.6.11 und eine einzelne Systemseite davor beträgt (z. B. 4096 Bytes auf (32-Bit) x86-Systemen). Der Code (include/linux/pipe_fs_i.h
, und fs/pipe.c
) scheint 16 Systemseiten zu verwenden (d. h. 64 KiB, wenn eine Systemseite 4 KiB groß ist), aber der Puffer für jede Pipe kann über ein fcntl angepasst werden auf der Pipe (bis zu einer maximalen Kapazität, die standardmäßig 1048576 Bytes beträgt, aber über /proc/sys/fs/pipe-max-size
geändert werden kann )).
Hier ist ein kleiner Bash /perl Kombination, mit der ich die Rohrkapazität meines Systems getestet habe:
#!/bin/bash
test $# -ge 1 || { echo "usage: $0 write-size [wait-time]"; exit 1; }
test $# -ge 2 || set -- "[email protected]" 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: %dn"
"$1" "$bytes_written"
Hier ist, was ich gefunden habe, als ich es mit verschiedenen Schreibgrößen auf einem Mac OS X 10.6.7-System ausgeführt habe (beachten Sie die Änderung für Schreibvorgänge mit mehr als 16 KB):
% /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
Wert, der in den C-Header-Dateien (und der pathconf Wert für _PC_PIPE_BUF
), gibt nicht die Kapazität von Pipes an, sondern die maximale Anzahl von Bytes, die atomar geschrieben werden können (siehe POSIX write(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. */