Bir boru tamponunun kapasitesi sistemlere göre değişir (ve aynı sistemde bile değişebilir). Bir borunun kapasitesini aramak için hızlı, kolay ve çapraz platform bir yöntem olduğundan emin değilim.
Örneğin, Mac OS X, varsayılan olarak 16384 baytlık bir kapasite kullanır, ancak boruya büyük yazma işlemi yapılırsa 65336 baytlık kapasiteye geçebilir veya çok fazla çekirdek belleği zaten varsa, tek bir sistem sayfasının kapasitesine geçecektir boru tamponları tarafından kullanılıyor (bakınız xnu/bsd/sys/pipe.h
ve xnu/bsd/kern/sys_pipe.c
; bunlar FreeBSD'den olduğundan, aynı davranış orada da olabilir).
Bir Linux boru (7) kılavuz sayfasında , boru kapasitesinin Linux 2.6.11'den beri 65536 bayt ve bundan önce tek bir sistem sayfası olduğunu söylüyor (örneğin (32-bit) x86 sistemlerinde 4096 bayt). Kod ( include/linux/pipe_fs_i.h
, ve fs/pipe.c
) , 16 sistem sayfasını kullanıyor gibi görünüyor (yani, bir sistem sayfası 4 KiB ise 64 KiB), ancak her borunun tamponu, borunun üzerindeki bir fcntl ile ayarlanabilir (varsayılan olarak 1048576 olan maksimum kapasiteye kadar). bayt, ancak üzerinden değiştirilebilir /proc/sys/fs/pipe-max-size
)).
İşte sistemimde boru kapasitesini test etmek için kullandığım bir bash / perl kombinasyonu:
#!/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"
İşte Mac OS X 10.6.7 sisteminde çeşitli yazma boyutlarıyla çalıştırırken bulduğum şey (16KiB'den büyük yazma değişikliklerine dikkat edin):
% /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
Linux 3.19'daki aynı komut dosyası:
/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
Not: PIPE_BUF
C başlık dosyalarında tanımlanan değer (ve bunun için pathconf değeri _PC_PIPE_BUF
), boruların kapasitesini değil, atomik olarak yazılabilecek maksimum bayt sayısını belirtir (bkz. POSIX yazma (2) ).
Şundan alıntı 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. */