GNU/Linux >> Tutoriales Linux >  >> Linux

¿Qué tan grande es el amortiguador de tubería?

Como comentario en Estoy confundido en cuanto a por qué “| true” en un archivo MAKE tiene el mismo efecto que “|| cierto” el usuario cjm escribió:

Otra razón para evitar | true es que si el comando produjera suficiente salida para llenar el búfer de canalización, bloquearía la espera de que true lo leyera.

¿Tenemos alguna forma de averiguar cuál es el tamaño del amortiguador de tuberías?

Respuesta aceptada:

La capacidad de un amortiguador de tuberías varía según los sistemas (e incluso puede variar en el mismo sistema). No estoy seguro de que haya una forma rápida, fácil y multiplataforma de buscar la capacidad de una tubería.

Mac OS X, por ejemplo, utiliza una capacidad de 16384 bytes de forma predeterminada, pero puede cambiar a capacidades de 65336 bytes si se realizan grandes escrituras en la canalización, o cambiará a una capacidad de una sola página del sistema si ya hay demasiada memoria del kernel. siendo utilizado por buffers de tubería (ver xnu/bsd/sys/pipe.h y xnu/bsd/kern/sys_pipe.c; dado que estos son de FreeBSD, el mismo comportamiento también puede ocurrir allí).

Una tubería(7) de Linux La página de manual dice que la capacidad de la tubería es de 65536 bytes desde Linux 2.6.11 y una sola página del sistema antes de eso (por ejemplo, 4096 bytes en sistemas x86 (32 bits)). El código (include/linux/pipe_fs_i.h y fs/pipe.c ) parece usar 16 páginas del sistema (es decir, 64 KiB si una página del sistema tiene 4 KiB), pero el búfer para cada conducto se puede ajustar a través de un fcntl en la tubería (hasta una capacidad máxima que por defecto es de 1048576 bytes, pero se puede cambiar a través de /proc/sys/fs/pipe-max-size )).

Aquí hay un pequeño bash /perla combinación que usé para probar la capacidad de la tubería en mi sistema:

#!/bin/bash
test $# -ge 1 || { echo "usage: $0 write-size [wait-time]"; exit 1; }
test $# -ge 2 || set -- "[email protected]" 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: %dn" 
    "$1" "$bytes_written"

Esto es lo que encontré ejecutándolo con varios tamaños de escritura en un sistema Mac OS X 10.6.7 (tenga en cuenta el cambio para escrituras de más de 16 KiB):

% /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

El mismo script en 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

Nota:El PIPE_BUF valor definido en los archivos de encabezado C (y el pathconf valor para _PC_PIPE_BUF ), no especifica la capacidad de las tuberías, sino el número máximo de bytes que se pueden escribir atómicamente (ver POSIX write(2) ).

Relacionado:Linux:¿imágenes de tubería ffmpeg extraídas del video?

Cita de 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.  */

Linux
  1. Cómo escribir un bucle en Bash

  2. ¿Cómo canalizo o redirijo la salida de curl -v?

  3. ¿Cómo puedo controlar lo que se coloca en el búfer de salida estándar y romperlo cuando se deposita una cadena específica en la tubería?

  4. ¿Cómo copiar el búfer de copia de pantalla GNU al portapapeles?

  5. Cómo canalizar los resultados de 'buscar' a mv en Linux

Cómo usar el comando dmesg de Linux

Cómo monitorear el progreso de los datos a través de una tubería usando el comando 'pv'

¿Cómo canalizar la lista de comandos que se muestra en "tab Complete"?

Cómo la nube hace que el análisis de Big Data sea más eficiente

Cómo escribir comandos fácilmente con el cmdlet Show-command de Powershell

¿Cómo aumento el búfer de desplazamiento hacia atrás en una sesión de pantalla en ejecución?