GNU/Linux >> Tutoriels Linux >  >> Linux

Quelle est la taille du tampon de tuyau ?

En tant que commentaire dans Je ne sais pas pourquoi "| true » dans un makefile a le même effet que « || vrai" l'utilisateur cjm a écrit :

Une autre raison d'éviter | true est que si la commande produisait suffisamment de sortie pour remplir le tampon de canal, elle bloquerait l'attente de true pour la lire.

Avons-nous un moyen de savoir quelle est la taille de la mémoire tampon ?

Réponse acceptée :

La capacité d'un tampon de tuyau varie selon les systèmes (et peut même varier sur le même système). Je ne suis pas sûr qu'il existe un moyen rapide, facile et multiplateforme de simplement rechercher la capacité d'un tuyau.

Mac OS X, par exemple, utilise une capacité de 16384 octets par défaut, mais peut passer à des capacités de 65336 octets si des écritures importantes sont effectuées dans le canal, ou passera à une capacité d'une seule page système si trop de mémoire du noyau est déjà utilisé par les tampons de canal (voir xnu/bsd/sys/pipe.h , et xnu/bsd/kern/sys_pipe.c; puisqu'ils proviennent de FreeBSD, le même comportement peut également se produire).

Un tuyau(7) Linux La page de manuel indique que la capacité du canal est de 65536 octets depuis Linux 2.6.11 et une seule page système avant cela (par exemple, 4096 octets sur les systèmes x86 (32 bits)). Le code (include/linux/pipe_fs_i.h , et fs/pipe.c ) semble utiliser 16 pages système (c'est-à-dire 64 Kio si une page système fait 4 Ko), mais le tampon pour chaque canal peut être ajusté via un fcntl sur le tuyau (jusqu'à une capacité maximale qui par défaut est de 1048576 octets, mais peut être modifiée via /proc/sys/fs/pipe-max-size )).

Voici un petit bash /perl combinaison que j'ai utilisée pour tester la capacité du tuyau sur mon système :

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

Voici ce que j'ai trouvé en l'exécutant avec différentes tailles d'écriture sur un système Mac OS X 10.6.7 (notez le changement pour les écritures supérieures à 16 Ko) :

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

Le même script sous 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

Remarque :Le PIPE_BUF valeur définie dans les fichiers d'en-tête C (et le pathconf valeur pour _PC_PIPE_BUF ), ne spécifie pas la capacité des tubes, mais le nombre maximum d'octets pouvant être écrits de manière atomique (voir POSIX write(2) ).

Connexes :Linux – Images de tuyaux ffmpeg extraites d'une vidéo ?

Citation de 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. Comment écrire stderr dans un fichier tout en utilisant tee avec un tuyau ?

  2. Comment canaliser ou rediriger la sortie de curl -v ?

  3. Comment puis-je surveiller ce qui est mis dans le tampon de sortie standard et casser lorsqu'une chaîne spécifique est déposée dans le tuyau?

  4. Comment diriger les résultats de 'find' vers mv sous Linux

  5. 8G RAM et SSD - quelle devrait être la taille de l'échange ?

Comment utiliser la commande Linux dmesg

Comment surveiller la progression des données dans un tube à l'aide de la commande "pv"

Comment canaliser la liste des commandes affichées par "onglet complet" ?

Comment écrire facilement des commandes à l'aide de l'applet de commande Powershell Show-command

Comment augmenter le tampon de défilement dans une session d'écran en cours d'exécution ?

Quelle doit être la taille de la partition swap ?