Công suất của bộ đệm ống khác nhau giữa các hệ thống (và thậm chí có thể thay đổi trên cùng một hệ thống). Tôi không chắc chắn có một cách nhanh chóng, dễ dàng và đa nền tảng để chỉ tìm kiếm công suất của một đường ống.
Ví dụ, Mac OS X sử dụng dung lượng 16384 byte theo mặc định, nhưng có thể chuyển sang dung lượng 65336 byte nếu ghi lớn được thực hiện cho đường ống hoặc sẽ chuyển sang dung lượng của một trang hệ thống nếu đã có quá nhiều bộ nhớ kernel được sử dụng bởi các bộ đệm ống (xem xnu/bsd/sys/pipe.h
, và xnu/bsd/kern/sys_pipe.c
; vì đây là từ FreeBSD, nên hành vi tương tự cũng có thể xảy ra ở đó).
Một trang man của Linux pipe (7) nói rằng dung lượng ống là 65536 byte kể từ Linux 2.6.11 và một trang hệ thống duy nhất trước đó (ví dụ 4096 byte trên các hệ thống x86 (32 bit)). Mã ( include/linux/pipe_fs_i.h
và fs/pipe.c
) dường như sử dụng 16 trang hệ thống (tức là 64 KiB nếu một trang hệ thống là 4 KiB), nhưng bộ đệm cho mỗi ống có thể được điều chỉnh thông qua một fcntl trên đường ống (tối đa công suất tối đa mặc định là 1048576 byte, nhưng có thể được thay đổi thông qua /proc/sys/fs/pipe-max-size
)).
Đây là một kết hợp bash / perl nhỏ mà tôi đã sử dụng để kiểm tra dung lượng đường ống trên hệ thống của mình:
#!/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"
Đây là những gì tôi tìm thấy khi chạy nó với các kích cỡ ghi khác nhau trên hệ thống Mac OS X 10.6.7 (lưu ý thay đổi đối với ghi lớn hơn 16KiB):
% /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
Kịch bản tương tự trên 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
Lưu ý: PIPE_BUF
Giá trị được xác định trong tệp tiêu đề C (và giá trị pathconf cho _PC_PIPE_BUF
), không chỉ định dung lượng của đường ống, nhưng số byte tối đa có thể được ghi nguyên tử (xem ghi POSIX (2) ).
Trích dẫn từ 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. */