open fscanf declarar como c file stdout buffering

fscanf - fwrite c



Cómo almacenar la salida estándar en la memoria y escribirla desde un subproceso dedicado (7)

¿Por qué no envuelves tu aplicación completa en otra? Básicamente, lo que quieres es un cat inteligente que copia stdin a stdout, almacenando en búfer según sea necesario. Luego use la redirección estándar de stdin / stdout. Esto se puede hacer sin modificar su aplicación actual en absoluto.

~MSalters/# YourCurrentApp | bufcat

Tengo una aplicación en C con muchos hilos de trabajo. Es esencial que estos no se bloqueen, por lo que cuando los subprocesos de trabajo necesitan escribir en un archivo en el disco, los tengo que escriban en un búfer circular en la memoria y luego tienen un subproceso dedicado para escribir ese búfer en el disco.

Los hilos de trabajo no bloquean más. El subproceso dedicado se puede bloquear de forma segura mientras se escribe en el disco sin afectar a los subprocesos de trabajo (no mantiene un bloqueo mientras se escribe en el disco). Mi memoria intermedia está sintonizada para ser lo suficientemente grande como para que el hilo del escritor pueda continuar.

Todo esto funciona muy bien. Mi pregunta es, ¿cómo implemento algo similar para stdout?

Podría macro printf () para escribir en un búfer de memoria, pero no tengo control sobre todo el código que podría escribir en la salida estándar (parte de ella está en bibliotecas de terceros).

¿Pensamientos? NickB


El método que usa el bigbuf 4096 solo funcionará. He intentado este código y, aunque captura con éxito la salida estándar en el búfer, no se puede utilizar en un caso del mundo real. No tiene forma de saber cuánto tiempo dura la salida capturada, así que no hay manera de saber cuándo terminar la cadena ''/ 0''. Si intentas usar el búfer, obtendrás 4000 caracteres de escupida de basura si has capturado con éxito 96 caracteres de la salida estándar.

En mi aplicación, estoy usando un intérprete de perl en el programa C. No tengo idea de cuánta salida se va a escupir del documento C que se lanza al programa, y ​​por lo tanto, el código anterior nunca me permitiría imprimir de forma limpia esa salida en cualquier lugar.


Me gusta la idea de usar freopen . También puede redirigir la dup2 a una canalización usando dup y dup2 , y luego usar la read para capturar datos de la tubería.

Algo así:

#include <stdio.h> #include <stdlib.h> #include <unistd.h> #define MAX_LEN 40 int main( int argc, char *argv[] ) { char buffer[MAX_LEN+1] = {0}; int out_pipe[2]; int saved_stdout; saved_stdout = dup(STDOUT_FILENO); /* save stdout for display later */ if( pipe(out_pipe) != 0 ) { /* make a pipe */ exit(1); } dup2(out_pipe[1], STDOUT_FILENO); /* redirect stdout to the pipe */ close(out_pipe[1]); /* anything sent to printf should now go down the pipe */ printf("ceci n''est pas une pipe"); fflush(stdout); read(out_pipe[0], buffer, MAX_LEN); /* read from pipe into buffer */ dup2(saved_stdout, STDOUT_FILENO); /* reconnect stdout for testing */ printf("read: %s/n", buffer); return 0; }


Puede "redirigir" la freopen() al archivo usando freopen() .

man freopen dice:

La función freopen () abre el archivo cuyo nombre es la cadena a la que apunta una ruta y asocia la secuencia a la que apunta la ruta. La secuencia original (si existe) está cerrada. El argumento de modo se usa igual que en la función fopen (). El uso principal de la función freopen () es cambiar el archivo asociado con una secuencia de texto estándar (stderr, stdin o stdout).

Este archivo bien podría ser una tubería. Las secuencias de trabajo se escribirán en esa tubería y la secuencia de escritura escuchará.




Una solución (para las dos cosas que está haciendo) sería utilizar una escritura de recopilación a través de writev .

Cada hilo podría, por ejemplo, incluirse en un búfer iovec y luego pasar los punteros iovec al subproceso del escritor y hacer que simplemente llame a writev con stdout.

Aquí hay un ejemplo del uso de writev de la Programación Avanzada de Unix.

Bajo Windows, usaría WSAsend para una funcionalidad similar.