GNU/Linux >> Linux Esercitazione >  >> Linux

Quanto è grande il buffer del tubo?

Come commento in sono confuso sul perché “| true” in un makefile ha lo stesso effetto di “|| true” l'utente cjm ha scritto:

Un altro motivo per evitare | true è che se il comando producesse un output sufficiente per riempire il buffer della pipe, bloccherebbe l'attesa di true per leggerlo.

Abbiamo un modo per scoprire qual è la dimensione del buffer di pipe?

Risposta accettata:

La capacità di un buffer per tubi varia tra i sistemi (e può anche variare sullo stesso sistema). Non sono sicuro che esista un modo rapido, facile e multipiattaforma per cercare semplicemente la capacità di un tubo.

Mac OS X, ad esempio, utilizza una capacità di 16384 byte per impostazione predefinita, ma può passare a capacità di 65336 byte se vengono effettuate scritture di grandi dimensioni sulla pipe, oppure passerà a una capacità di una singola pagina di sistema se è già presente troppa memoria del kernel utilizzato dai buffer di pipe (vedi xnu/bsd/sys/pipe.h e xnu/bsd/kern/sys_pipe.c; dato che provengono da FreeBSD, lo stesso comportamento potrebbe verificarsi anche lì).

Un Linux pipe(7) la pagina man dice che la capacità della pipe è di 65536 byte da Linux 2.6.11 e una singola pagina di sistema precedente (ad esempio 4096 byte su sistemi x86 (a 32 bit). Il codice (include/linux/pipe_fs_i.h e fs/pipe.c ) sembra utilizzare 16 pagine di sistema (ovvero 64 KiB se una pagina di sistema è 4 KiB), ma il buffer per ogni pipe può essere regolato tramite un fcntl sulla pipe (fino a una capacità massima che per impostazione predefinita è 1048576 byte, ma può essere modificata tramite /proc/sys/fs/pipe-max-size )).

Ecco una piccola bash /perl combinazione che ho usato per testare la capacità del tubo sul mio sistema:

#!/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"

Ecco cosa ho trovato eseguendolo con varie dimensioni di scrittura su un sistema Mac OS X 10.6.7 (nota la modifica per scritture superiori a 16 KiB):

% /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

Lo stesso script su 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

Nota:il PIPE_BUF valore definito nei file di intestazione C (e nel pathconf valore per _PC_PIPE_BUF ), non specifica la capacità delle pipe, ma il numero massimo di byte che possono essere scritti atomicamente (vedi POSIX write(2) ).

Correlati:Linux – immagini pipe ffmpeg estratte dal video?

Citazione da 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. Come scrivo stderr su un file mentre uso tee con una pipe?

  2. Come posso reindirizzare o reindirizzare l'output di curl -v?

  3. Come posso monitorare ciò che viene inserito nel buffer di uscita standard e rompersi quando una stringa specifica viene depositata nella pipe?

  4. 8G RAM e SSD:quanto dovrebbe essere grande lo scambio?

  5. Come contare il numero di byte in un file, raggruppando gli stessi byte?

Come scrivere un ciclo in Bash

Come utilizzare il comando Linux dmesg

Come monitorare l'avanzamento dei dati attraverso un tubo utilizzando il comando "pv".

Come scrivere facilmente comandi utilizzando il cmdlet di Powershell Show-command

Come posso aumentare il buffer di scorrimento all'indietro in una sessione dello schermo in esecuzione?

Come reindirizzare il testo dalla riga di comando agli appunti