¿El tamaño del búfer de tubería es 4k o 64k?

4 minutos de lectura

avatar de usuario
gui13

Leí en varios lugares que el tamaño de búfer predeterminado para una tubería es de 4 kB (por ejemplo, aquí), y mi ulimit -a tiende a confirmar esa afirmación:

$ 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

Pero cuando uso un pequeño programa para probar el tamaño del búfer (escribiendo en la canalización hasta que se bloquee write()), ¡veo un límite de 64kB!

Ver este programa:

#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;
}

Y su salida:

$ ./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]

¡Sugiere fuertemente que el tamaño del búfer de tubería es en realidad 64k! ¿¿Que está sucediendo aquí??

  • Esta pregunta tiene ahora dos años y el tamaño en cuestión ahora es programable: stackoverflow.com/a/13906354/140740

    – DigitalRoss

    16 de diciembre de 2012 a las 23:17

Las otras respuestas le dicen que el tamaño de la tubería es de 64 KB. La razón por la que PIPE_BUF es de 4 KB es que PIPE_BUF es el tamaño más grande para el que se garantiza que las escrituras serán atómicas. Ver http://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html

  • ¿Esto implica que los búferes pueden aumentar arbitrariamente? ¿Pero la escritura atómica garantizada está limitada a 4K?

    – Subomi

    20 de julio de 2018 a las 6:33

avatar de usuario
DigitalRoss

ya es programable


A partir de Linux 2.6.35 puedes usar fcntl(2) con el F_SETPIPE_SZ operación para configurar el amortiguador de tubería hasta /proc/sys/fs/pipe-max-size. Esto es por defecto 1 MB; ver proceso(5).

  • Si pero no. El tamaño de la tubería es anunciado por ulimit todavía es 4kB en Kernel 3.2 (el que tengo aquí). Mi pregunta era sobre PIPE_BUF, que es lo que respondió janneb: PIPE_BUF es una constante y es el tamaño máximo de una escritura que será atómica cuando se realice (es decir, seguro para subprocesos;)).

    – Gui13

    17 de diciembre de 2012 a las 12:55

  • ¿Significa esto que al configurar más de 4 KB aún puede garantizar que la escritura sea atómica?

    – usuario1767754

    9 de noviembre de 2017 a las 23:06

En mi experiencia, la prueba de escritura única produjo un tamaño total de 65536, sin embargo, cuando escribí 2700 a la vez, solo pude escribir 16 veces, y luego el siguiente intento se detuvo. Me imagino que la escritura ‘atómica’ debe estar dentro de un bloque de 4K, y que para cada una de mis escrituras, va al siguiente bloque completo para satisfacer la solicitud. Entonces, en efecto, el tamaño de tubería utilizable depende del tamaño de sus escrituras.

Parece que el kernel usa hasta 16 búferes que suman 64k. Mira esto Enlace para obtener una explicación de la salida ulimit frente al tamaño real del búfer

avatar de usuario
nos

Así es. Desde el núcleo 2.6.11, el tubo el tamaño en Linux es de 64kB. Por qué ulimit lo reporta como 4Kb, no estoy seguro, pero está mal.

  • Rah, el mismo enlace que el que señalé en mi pregunta. No vi la línea que decía 64k… De todos modos, por qué ulimit dice 4K es un misterio para mí…

    – Gui13

    7 de enero de 2011 a las 10:05


  • Solo ksh y bash ulimit incorporado informan que tamaño de la tuberíapero no es un límite establecido por setrlimit, y no es el tamaño de los búfer de tubería, es solo PIPE_BUF, el tamaño máximo para el cual se garantiza que una escritura () en una tubería sea atómica.

    – Stéphane Chazelas

    14/09/2015 a las 11:25

  • Rah, el mismo enlace que el que señalé en mi pregunta. No vi la línea que decía 64k… De todos modos, por qué ulimit dice 4K es un misterio para mí…

    – Gui13

    7 de enero de 2011 a las 10:05


  • Solo ksh y bash ulimit incorporado informan que tamaño de la tuberíapero no es un límite establecido por setrlimit, y no es el tamaño de los búfer de tubería, es solo PIPE_BUF, el tamaño máximo para el cual se garantiza que una escritura () en una tubería sea atómica.

    – Stéphane Chazelas

    14/09/2015 a las 11:25

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad