La capacité d'un tampon de tuyauterie varie d'un système à l'autre (et peut même varier sur le même système). Je ne suis pas sûr qu'il existe un moyen rapide, simple et multiplateforme de simplement rechercher la capacité d'un tuyau.
Mac OS X, par exemple, utilise une capacité de 16 384 octets par défaut, mais peut passer à une capacité de 65 336 octets si une écriture de grande taille est effectuée dans le canal, ou passera à une capacité d'une seule page système si la mémoire du noyau est déjà trop importante. utilisé par les tampons de pipe (voir xnu/bsd/sys/pipe.h
, et xnu/bsd/kern/sys_pipe.c
; puisque ceux-ci proviennent de FreeBSD, le même comportement peut se produire là aussi).
Une page de manuel pipe (7) de Linux indique que la capacité de la conduite est de 65 536 octets depuis Linux 2.6.11 et d'une seule page système antérieure à celle-ci (par exemple, 4096 octets sur des 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 Ko si une page système est de 4 Ko), mais le tampon de chaque conduite peut être ajusté via un fcntl sur la conduite (jusqu’à une capacité maximale de 1048576 par défaut) octets, mais peut être modifié via /proc/sys/fs/pipe-max-size
)).
Voici une petite combinaison bash / perl que j'ai utilisée pour tester la capacité de conduite de mon système:
#!/bin/bash
test $# -ge 1 || { echo "usage: $0 write-size [wait-time]"; exit 1; }
test $# -ge 2 || set -- "$@" 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: %d\n" \
"$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: La PIPE_BUF
valeur définie dans les fichiers d'en-tête C (et la valeur de pathconf pour _PC_PIPE_BUF
) ne spécifie pas la capacité des canaux, mais le nombre maximal 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. */