c - limpiar - setbuf para que sirve
¿Puede un programa llamar a fflush() en el mismo ARCHIVO*al mismo tiempo? (5)
La respuesta real parece ser que las transmisiones son (se supone que son) seguras para subprocesos, pero, si ese no fuera el caso, su problema podría ser que se produzca un fflush
(fuera de un bloqueo) mientras que otro subproceso está escribiendo (dentro de un crítico). sección).
Como tal, trabajaría con el modelo de la máquina virtual contra la que está codificando y también pondría fflush()
dentro de una sección crítica.
¿Puede suceder algo malo (como comportamiento indefinido, corrupción de archivos, etc.) si varios subprocesos llaman simultáneamente a fflush()
en la misma variable FILE*
?
Aclaración: no me refiero a escribir el archivo al mismo tiempo. Sólo me refiero a lavarlo al mismo tiempo.
Los subprocesos no leen ni escriben el archivo simultáneamente (solo escriben el archivo dentro de una sección crítica, un subproceso a la vez). Solo salen de la sección crítica, para liberar la sección crítica antes y así permitir que los demás hagan el otro trabajo (excepto la escritura del archivo).
Aunque puede suceder que un hilo esté escribiendo el archivo (dentro de la sección crítica), mientras que otro hilo (s) está vaciando el archivo (fuera de la sección crítica).
Las transmisiones en C 1 son seguras para subprocesos 2 . Se requieren funciones para bloquear la transmisión antes de acceder a ella 3 .
La función fflush es segura para subprocesos y puede invocarse desde cualquier subproceso en cualquier momento, siempre que el flujo sea un flujo de salida o un flujo de actualización 4 .
1 Según el estándar actual, que es C11.
2 (Citado de: ISO / IEC 9899: 201x 7.21.3 Transmisiones 7)
Cada flujo tiene un bloqueo asociado que se utiliza para evitar las carreras de datos cuando varios subprocesos de ejecución acceden a un flujo, y para restringir el entrelazado de las operaciones de flujo realizadas por varios subprocesos. Sólo un hilo puede mantener este bloqueo a la vez. El bloqueo es reentrante: un solo hilo puede mantener el bloqueo varias veces en un momento dado.
3 (Citado de: ISO / IEC 9899: 201x 7.21.3 Transmisiones 8)
Todas las funciones que leen, escriben, posicionan o consultan la posición de un flujo bloquean el flujo antes de acceder a él. Liberan el bloqueo asociado con el flujo cuando se completa el acceso. reentrante: un solo hilo puede mantener el bloqueo varias veces en un momento dado.
4 (Citado de: ISO / IEC 9899: 201x 7.21.5.2 La función fflush 2)
Si el flujo apunta a un flujo de salida o un flujo de actualización en el que no se ingresó la operación más reciente, la función fflush hace que cualquier dato no escrito para ese flujo se entregue al entorno del host para que se escriba en el archivo; de lo contrario, el comportamiento es indefinido.
POSIX.1c requiere que POSIX.1c ejecute las funciones de lenguaje POSIX.1 y C que operan en secuencias de caracteres (representadas por punteros a objetos de tipo FILE) de tal manera que se logre la reentrada (ver ISO / IEC 9945: 1- 1996, §8.2).
Este requisito tiene un inconveniente; impone penalizaciones sustanciales en el rendimiento debido a la sincronización que debe incorporarse en las implementaciones de las funciones en aras de la reentrada. POSIX.1c aborda este compromiso entre la reentrada (seguridad) y el rendimiento mediante la introducción de alto rendimiento, pero no reentrante (potencialmente insegura), versiones de las siguientes funciones de E / S estándar en lenguaje C: getc (), getchar (), putc () y putchar (). Las versiones no reentrantes se llaman getc_unlocked (), y así sucesivamente, para resaltar su inseguridad.
Sin embargo, tenga en cuenta que otros ya lo han señalado: muchos sistemas populares (incluidos Windows y Android) no son compatibles con POSIX.
Respuesta bastante simple, no puede hacer eso, ya que el archivo tiene una sola "posición actual". ¿Cómo se mantiene al tanto? ¿El archivo está abierto para acceso secuencial o aleatorio? En este último caso, podría abrirlo varias veces (una para cada subproceso) y aún así idear formas de mantener la estructura del archivo consistente.
Se supone que no debe llamar a fflush()
en un flujo de entrada, esto invoca un comportamiento indefinido, por lo que asumiré que el flujo está abierto en modo de escritura o actualización.
Si el flujo está abierto en modo de actualización ( "w+"
o "r+"
), la última operación no debe ser una lectura cuando llama a fflush()
. Dado que el flujo se utiliza en varios subprocesos de forma asíncrona, sería difícil garantizar esto sin algún tipo de comunicación entre procesos y sincronización o bloqueo si realiza alguna lectura. Todavía hay una razón válida para abrir el archivo en modo de actualización, pero asegúrese de no hacer ninguna lectura después de iniciar el subproceso de fflush
.
fflush()
no modifica la posición actual. Simplemente hace que cualquier salida en búfer se escriba en el sistema. Los flujos generalmente están protegidos por un bloqueo, por lo que llamar a fflush()
en un hilo no debe fflush()
la salida realizada por otro hilo, pero puede cambiar la sincronización de las escrituras del sistema. Si múltiples hilos emiten el mismo FILE*
, el orden en el que se produce el intercalado es indeterminado de todos modos. Además, si usa fseek()
hay hilos diferentes para el mismo flujo, debe usar su propio bloqueo para garantizar la coherencia entre el fseek()
y la siguiente salida.
Aunque parece estar bien hacerlo, probablemente no sea recomendable. En su lugar, podría llamar a fflush()
después de las operaciones de escritura en cada hilo, antes de liberar el bloqueo.