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