GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Wie groß ist der Pipe-Puffer?

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) ).

Verwandte:Linux – ffmpeg-Pipe-Bilder aus Video extrahiert?

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.  */

Linux
  1. Wie man die Ergebnisse von 'find' unter Linux an mv weiterleitet

  2. 8G RAM und SSD – wie groß sollte der Swap sein?

  3. Wie kann man die Anzahl der Bytes in einer Datei zählen und dieselben Bytes gruppieren?

  4. Wie kann ich etwas zum Audioausgang leiten?

  5. Wie groß sollte die Swap-Partition sein?

So verwenden Sie den dmesg-Linux-Befehl

So überwachen Sie den Fortschritt von Daten durch eine Pipe mit dem Befehl „pv“.

So schreiben Sie einfach Befehle mit dem Powershell-Cmdlet Show-command

Wie erhöhe ich den Scrollback-Puffer in einer laufenden Bildschirmsitzung?

Wie kopiere ich den Kopierpuffer von GNU Screen in die Zwischenablage?

So leiten Sie Text von der Befehlszeile in die Zwischenablage