Размер буфера для труб равен 4k или 64k?
Я читал в нескольких местах, что размер буфера по умолчанию для канала равен 4kB (например, здесь), а мой ulimit -a
имеет тенденцию подтверждать это утверждение:
$ ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 15923
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8 // 8 * 512B = 4kB
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 10240
cpu time (seconds, -t) unlimited
max user processes (-u) 1024
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
Но когда я использую небольшую программу для проверки размера буфера (записывая в трубку до блоков write()), я вижу предел в 64 КБ!
Смотрите эту программу:
#include <stdio.h>
#include <unistd.h>
#include <limits.h>
int main(void)
{
int tube[2];
char c = 'c';
int i;
fprintf(stdout, "Tube Creation\n");
fprintf(stdout, "Theoretical max size: %d\n", PIPE_BUF);
if( pipe(tube) != 0)
{
perror("pipe");
_exit(1);
}
fprintf(stdout, "Writing in pipe\n");
for(i=0;; i++)
{
fprintf(stdout, "%d bytes written\n", i+1);
if( write(tube[1], &c, 1) != 1)
{
perror("Write");
_exit(1);
}
}
return 0;
}
И его вывод:
$ ./test_buf_pipe
Tube Creation
Theoretical max size: 4096
Writing in pipe
1 bytes written
2 bytes written
3 bytes written
4 bytes written
[...]
65535 bytes written
[blocks here]
Это говорит о том, что размер буфера для буфера на самом деле составляет 64 КБ!
Что здесь происходит?
Ответы
Ответ 1
Другие ответы говорят вам, что размер трубы составляет 64 КБ. Причина, по которой PIPE_BUF составляет 4 КБ, заключается в том, что PIPE_BUF является наибольшим размером, для которого записи гарантированно являются атомарными. См. http://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html
Ответ 2
Теперь он программируется
В Linux 2.6.35 вы можете использовать fcntl (2) с помощью операции F_SETPIPE_SZ
для установки буфер трубы до /proc/sys/fs/pipe-max-size
. Это по умолчанию 1 МБ; см. proc (5).
Ответ 3
По моему опыту, одиночный тест на запись дал общий размер 65536, но когда я писал 2700 за раз, я мог писать только 16 раз, а затем следующая попытка киосков. Я полагаю, что "атомная" запись должна находиться в пределах одного блока 4 КБ, и для каждой моей записи он переходит к следующему полному блоку, чтобы удовлетворить запрос. Таким образом, используемый размер трубы зависит от размера вашей записи.
Ответ 4
Похоже, что в ядре используется до 16 буферов, которые добавляют до 64k.
См. Ссылку для объяснения вывода ulimit и фактического размера буфера
Ответ 5
Это правильно. Начиная с ядра 2.6.11 размер pipe в Linux равен 64 КБ. Почему ulimit сообщает об этом как 4Kb, я не уверен, но это неправильно.