ความจุของไพพ์บัฟเฟอร์แตกต่างกันไปตามระบบ (และอาจแตกต่างกันไปในระบบเดียวกัน) ฉันไม่แน่ใจว่ามีวิธีที่รวดเร็วง่ายและข้ามแพลตฟอร์มเพื่อค้นหาความจุของไพพ์
ตัวอย่างเช่น Mac OS X ใช้ความจุ 16384 ไบต์ตามค่าเริ่มต้น แต่สามารถเปลี่ยนเป็นความจุ 65336 ไบต์หากการเขียนขนาดใหญ่ถูกทำกับไพพ์หรือจะเปลี่ยนเป็นความจุของหน้าระบบเดียวหากหน่วยความจำเคอร์เนลมากเกินไปอยู่แล้ว ถูกใช้โดยบัฟเฟอร์ไปป์ (ดูxnu/bsd/sys/pipe.h
และxnu/bsd/kern/sys_pipe.c
เนื่องจากสิ่งเหล่านี้มาจาก FreeBSD พฤติกรรมแบบเดียวกันอาจเกิดขึ้นที่นั่นเช่นกัน)
หนึ่งหน้า man Linux ท่อ (7)บอกว่าความจุของท่อเป็น 65536 ไบต์ตั้งแต่ Linux 2.6.11 และหน้าระบบเดียวก่อนหน้านั้น (เช่น 4096 ไบต์บนระบบ x86 (32 บิต) x86) โค้ด ( include/linux/pipe_fs_i.h
และfs/pipe.c
) ดูเหมือนว่าจะใช้หน้าระบบ 16 หน้า (เช่น 64 KiB หากหน้าระบบคือ 4 KiB) แต่บัฟเฟอร์สำหรับแต่ละไพพ์สามารถปรับได้ผ่านfcntlบนไพพ์ (สูงสุดความจุสูงสุดซึ่งเป็นค่าเริ่มต้นที่ 1048576 ไบต์ แต่สามารถเปลี่ยนแปลงได้ผ่าน/proc/sys/fs/pipe-max-size
))
นี่คือชุดค่าผสมbash / perlเล็กน้อยที่ฉันใช้ทดสอบความจุของท่อในระบบของฉัน:
#!/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"
นี่คือสิ่งที่ฉันพบว่ารันด้วยขนาดการเขียนที่หลากหลายบนระบบ Mac OS X 10.6.7 (สังเกตการเปลี่ยนแปลงสำหรับการเขียนที่ใหญ่กว่า 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
สคริปต์เดียวกันบน 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
หมายเหตุ: PIPE_BUF
ค่าที่กำหนดในไฟล์ส่วนหัว C (และค่าpathconfสำหรับ_PC_PIPE_BUF
) ไม่ได้ระบุความจุของไพพ์แต่จำนวนไบต์สูงสุดที่สามารถเขียนแบบอะตอมมิก (ดูPOSIX write (2) )
อ้างอิงจาก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. */