En C, ¿cuál es el tamaño del búfer de salida estándar?

8 minutos de lectura

Hoy aprendí que stdout tiene un búfer de línea cuando se configura en terminal y se almacena en búfer en diferentes casos. Entonces, en una situación normal, si uso printf() sin terminar ‘\n’, se imprimirá en la pantalla solo cuando el búfer esté lleno. ¿Cómo obtener un tamaño de este búfer, qué tan grande es esto?

  • Si no desea el almacenamiento en búfer, ¿por qué no usar una de las otras funciones de biblioteca estándar que no lo requieren? O tal vez podría simplemente incluir el \n terminador

    – Roberto Harvey

    5 de junio de 2012 a las 20:03


  • Simplemente no sé cuál es el tamaño del búfer de salida estándar. Sé lo que dijiste, solo quiero saber cuántos datos se deben recopilar para que el búfer se considere lleno y el texto se imprima en la pantalla

    – usuario1042840

    5 de junio de 2012 a las 20:12

En C ¿cual es el tamano del bufer de salida
Juan Bode

El tamaño real está definido por la implementación individual; el estándar no exige un tamaño mínimo (según lo que he podido encontrar, de todos modos). No tengo ni idea de cómo determinaría el tamaño del búfer.

Editar

capítulo y verso:

7.19.3 Archivos


3 Cuando un arroyo es sin búfer, los caracteres están destinados a aparecer desde el origen o en el destino lo antes posible. De lo contrario, los caracteres pueden acumularse y transmitirse hacia o desde el entorno anfitrión como un bloque. Cuando una corriente es totalmente almacenado en búfer, los caracteres están destinados a ser transmitidos hacia o desde el entorno host como un bloque cuando se llena un búfer. Cuando una corriente es línea almacenada en búfer, los caracteres están destinados a transmitirse hacia o desde el entorno del host como un bloque cuando se encuentra un carácter de nueva línea. Además, los caracteres están destinados a ser transmitidos como un bloque al entorno del host cuando se llena un búfer, cuando se solicita la entrada en un flujo sin búfer o cuando se solicita la entrada en un flujo de línea con búfer que requiere la transmisión de caracteres desde el entorno del host. . El soporte para estas características está definido por la implementación y puede verse afectado a través de la setbuf y setvbuf funciones.

Énfasis añadido.

“Implementación definida” no es un eufemismo para “No lo sé”, es simplemente una declaración de que el estándar del lenguaje lo deja explícitamente en manos del implementación para definir el comportamiento.

Y dicho esto, hay es una forma no programática de averiguarlo; consulte la documentación de su compilador. “Implementación definida” también significa que la implementación deber documentar el comportamiento:

3.4.1

1 comportamiento definido por la implementación

comportamiento no especificado donde cada implementación documenta cómo se hace la elección

2 EJEMPLO Un ejemplo de comportamiento definido por la implementación es la propagación del bit de orden superior cuando un entero con signo se desplaza a la derecha.

  • Escucho ‘depende de la implementación’ con tanta frecuencia que empiezo a pensar que a veces es solo la forma de decir ‘No sé’, pero lo has dicho claramente, así que está bien ;p

    – usuario1042840

    5 de junio de 2012 a las 20:44

  • “depende de la implementación” significa que el implementador puede implementarlo como mejor le parezca y aún así cumplir con el estándar. si realmente quiere saber qué tan grande es ese búfer, puede seguir escribiendo en él sin ningún “\n” hasta que se desborde.

    – Pizza

    5 de junio de 2012 a las 21:07

  • ¿Cómo puedo ver si el búfer se desborda, finalmente no se imprimirán caracteres y comenzará desde 1 nuevamente?

    – usuario1042840

    5 de junio de 2012 a las 21:11

  • puedes imprimir el conteo del caracter a stderr (que es sin búfer) y ver cuando salen los primeros caracteres con búfer, te dejo la implementación como tarea.

    – Pizza

    5 de junio de 2012 a las 21:15

  • Esto realmente depende de la libc que esté usando, no del compilador.

    – Alex D.

    11 de agosto de 2015 a las 7:44

1647674888 696 En C ¿cual es el tamano del bufer de salida
locuaz

Se usa Linux cuando se crea una tubería para el tamaño de tubería predeterminado 64K. En /proc/sys/fs/pipe-max-size existe el tamaño máximo de tubería. Para el valor predeterminado 1048576 es típico.

Para el búfer de archivos predeterminado de glibc; 65536 bytes parece razonable. Sin embargo, determinado por grep del árbol fuente de glibc: libio/libio.h:#define _IO_BUFSIZ _G_BUFSIZ sysdeps/generic/_G_config.h:#define _G_BUFSIZ 8192 sysdeps/unix/sysv/linux/_G_config.h:#define _G_BUFSIZ 8192

Por eso, la pregunta original podría o no ser respondida. Para el esfuerzo de un minuto, la mejor suposición es de 8 kilobytes.

Para el simple almacenamiento en búfer de línea, 8K es adecuado. Sin embargo, para más de una línea de salida almacenada en búfer en comparación con 64K; 8K no es eficiente. Porque para el tamaño de tubería predeterminado se usa 64K y si no se espera un tamaño de tubería más grande y si no se establece explícitamente un tamaño de tubería más grande, se recomienda 64K para un búfer de stdio.

Si se requiere rendimiento, los escasos búferes de 8K no son suficientes. Mediante fcntl(pipefd,F_SETPIPE_SZ,1048576) se puede aumentar el tamaño de una tubería. Mediante setvbuf (stdout,buffer,_IOFBF,1048576) se puede reemplazar un búfer de archivo proporcionado por stdio. Si no se utiliza una tubería, el tamaño de la tubería es irrelevante. Sin embargo, si los datos entre dos procesos se canalizan, al aumentar el tamaño de la canalización, podría convertirse en una mejora del rendimiento. De lo contrario, por el búfer más pequeño o por la tubería más pequeña se crea un cuello de botella.

Si se lee también, entonces mediante un búfer más grande por stdio, es posible que se requieran menos invocaciones de funciones de lectura. Por la palabra “podría” se sugiere una consideración importante. Como lo proporciona una única invocación de función de escritura mediante una única invocación de función de lectura, se puede leer la mayor cantidad de datos. Al invocar una función de lectura, se puede esperar un retorno con menos bytes de los solicitados. Mediante una invocación de función de lectura adicional, se pueden obtener bytes adicionales.

Para escribir una línea de datos; por stdio overkill se proporciona. Sin embargo, es posible la salida con búfer de la línea stdio. En algunos escenarios, la salida con búfer de línea es esencial. Si se escribe en un archivo proporcionado por un sistema de archivos virtual proc o si se escribe en un archivo proporcionado por un sistema de archivos virtual sys, en un solo búfer de escritura se debe incluir el byte de salto de línea. Si se utiliza una segunda escritura, podría producirse un resultado inesperado.

Si se mezclan lectura, escritura y stdio, existen advertencias. Antes de una invocación de función de escritura, se requiere una invocación de función fflush. Porque stderr no está almacenado en búfer; para stderr no se requiere la invocación de la función fflush. Al leer, es posible que se proporcionen menos bytes de los esperados. Por stdio, es posible que los bytes anteriores ya estén almacenados en el búfer.

No mezclar E/S unistd y stdio es un buen consejo, pero a menudo se ignora. Mezclar entradas almacenadas en búfer no es razonable. Es posible mezclar entradas sin búfer. La mezcla de salida almacenada en búfer es plausible.

Por stdio buffered IO se proporciona comodidad. Sin stdio buffered IO es posible. Sin embargo, para el código se requieren bytes adicionales. Cuando se aprovecha un búfer de tamaño suficiente; en comparación con las funciones de salida proporcionadas por stdio; la invocación de la función de escritura no es necesariamente más lenta.

Sin embargo, cuando no hay una tubería involucrada, se puede proporcionar una E/S superior mediante la función mmap. En una tubería por mmap no se devuelve un error. Sin embargo, en el espacio de direcciones no se proporcionan los datos. En una tubería por lseek se proporciona un error.

Por último, man 3 setvbuf proporciona un buen ejemplo. Si en la pila se asigna el búfer, entonces, antes de una devolución, no se debe omitir la invocación de la función fclose.

La pregunta real era “En C, ¿cuál es el tamaño del búfer de salida estándar?” Para 8192 eso podría ser respondido.

Para aquellos que se encuentran con esta consulta, podría existir curiosidad sobre la eficiencia de entrada/salida del búfer. Mediante algunas indagaciones se aborda implícitamente el objetivo. Por una preferencia por las respuestas concisas, no se explica el significado del tamaño de la tubería y el tamaño del búfer y mmap. Esta respuesta explica.

1647674889 910 En C ¿cual es el tamano del bufer de salida
fduff

aquí son algunas respuestas bastante interesantes sobre una pregunta similar.

en un sistema Linux puede ver los tamaños de búfer de diferentes funciones, incluyendo ulimit. También los archivos de encabezado limits.h y pipe.h debe contener ese tipo de información.

En C ¿cual es el tamano del bufer de salida
kfh

Puede configurarlo como sin búfer o simplemente vaciarlo.

Esto parece tener información decente cuando el tiempo de ejecución de C normalmente lo vacía por usted y algunos ejemplos. Echa un vistazo a esta.

¿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