running name how c linux unix operating-system

how - name of process linux



stdout thread-safe en C en Linux? (5)

Ambos son seguros para subprocesos hasta el punto de que la aplicación no se bloqueará si varios subprocesos los llaman en el mismo descriptor de archivo. Sin embargo, sin un cierto nivel de aplicación de bloqueo, lo que está escrito podría ser intercalado.

¿Está escribiendo en stdout usando printf thread-safe en Linux? ¿Qué pasa con el uso del comando de write nivel más bajo?


C obtuvo un nuevo estándar desde que se hizo esta pregunta (y la última respuesta).

C11 ahora viene con soporte para subprocesos múltiples y trata el comportamiento multiproceso de flujos:

§7.21.2 Flujos

¶7 Cada flujo tiene un bloqueo asociado que se utiliza para evitar carreras de datos cuando varios subprocesos de ejecución acceden a un flujo y para restringir el entrelazado de operaciones de flujo realizadas por varios subprocesos. Solo 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.

¶8 Todas las funciones que leen, escriben, posicionan o consultan la posición de una secuencia bloquean la transmisión antes de acceder a ella. Liberan el bloqueo asociado con la transmisión cuando se completa el acceso.

Por lo tanto, una implementación con subprocesos C11 debe garantizar que el uso de printf es seguro para subprocesos.

Si la atomicidad (como en ningún intercalado 1 ) está garantizada, no fue claro para mí a primera vista, porque el estándar hablaba de restringir el entrelazado, en lugar de prevenir , que ordenaba para carreras de datos.

Me inclino hacia que se garantice. El estándar habla de restringir el entrelazado, ya que todavía se permite que ocurra algún entrelazado que no cambie el resultado; ej. , fseek algunos bytes, vuelve a fseek algunos más y fwrite hasta el desplazamiento original, de modo que ambos fwrite s estén espalda con espalda. La implementación es libre de reordenar estas 2 fwrite y combinarlas en una sola escritura.

1 : Ver el texto de 1 en 1 para un ejemplo.


Es seguro para subprocesos; printf debe ser reentrante, y no causarás ninguna extrañeza o corrupción en tu programa.

No puede garantizar que su salida de un hilo no comience a la mitad de la salida de otro hilo. Si te preocupa, debes desarrollar tu propio código de salida bloqueado para evitar el acceso múltiple.


No está especificado por el estándar C; depende de la implementación de la biblioteca estándar C. De hecho, el estándar C ni siquiera menciona los hilos, ya que ciertos sistemas (por ejemplo, los sistemas integrados) no tienen subprocesamiento múltiple.

En la implementación de GNU ( glibc ), la mayoría de las funciones de nivel superior en stdio que tratan con objetos FILE* son seguras para subprocesos. Los que normalmente no están unlocked en sus nombres (por ejemplo, getc_unlocked(3) ). Sin embargo, la seguridad de subprocesos está en un nivel de llamada por función: si realiza múltiples llamadas a printf(3) , por ejemplo, se garantiza que cada una de esas llamadas saldrá atómicamente, pero otros subprocesos pueden imprimir cosas entre sus llamadas a printf() . Si desea asegurarse de que una secuencia de llamadas de E / S se distribuye atómicamente, puede rodearlas con un par de flockfile(3)/funlockfile(3) para bloquear el identificador FILE . Tenga en cuenta que estas funciones son reentrantes, por lo que puede llamar de manera segura a printf() entre ellas, y eso no dará lugar a un punto muerto, aunque el propio printf() haga una llamada a flockfile() .

Las llamadas de E / S de bajo nivel como write(2) deben ser seguras para hilos, pero no estoy 100% seguro de eso: write() hace una llamada al kernel para realizar I / O. Cómo exactamente sucede esto depende de qué kernel estás usando. Puede ser la instrucción sysenter o la instrucción int (interrupt) en sistemas anteriores. Una vez dentro del kernel, depende del kernel asegurarse de que la E / S sea segura para la ejecución de subprocesos. En una prueba que acabo de hacer con Darwin Kernel Version 8.11.1, write(2) parece ser seguro para subprocesos.


Si lo llamarías "seguro para subprocesos" depende de tu definición de seguridad de subprocesos. POSIX requiere que stdio funciones stdio utilicen el bloqueo, por lo que su programa no se bloqueará, dañará los estados del objeto FILE , etc. si usa printf simultáneamente desde múltiples hilos. Sin embargo, todas stdio operaciones de stdio se especifican formalmente en términos de llamadas repetidas a fgetc y fputc , por lo que no se garantiza la atomicidad a mayor escala. Es decir, si los subprocesos 1 y 2 intentan imprimir "Hello/n" y "Goodbye/n" al mismo tiempo, no hay garantía de que la salida será "Hello/nGoodbye/n" o "Goodbye/nHello/n" . Podría ser "HGelolodboy/ne/n" . En la práctica, la mayoría de las implementaciones adquirirán un único bloqueo para toda la llamada de escritura de nivel superior simplemente porque es más eficiente, pero su programa no debería asumirlo. Puede haber casos de esquina donde esto no se hace; por ejemplo, una implementación probablemente podría omitir por completo el bloqueo de flujos sin búfer.

Editar: El texto anterior sobre atomicidad es incorrecto. POSIX garantiza que todas stdio operaciones de stdio son atómicas, pero la garantía está oculta en la documentación de flockfile : http://pubs.opengroup.org/onlinepubs/9699919799/functions/flockfile.html

Todas las funciones que hacen referencia a objetos (FILE *) se comportarán como si usaran flockfile () y funlockfile () internamente para obtener la propiedad de estos objetos (FILE *).

Puede usar las flockfile , ftrylockfile y funlockfile usted mismo para lograr escrituras atómicas más grandes que una llamada de función única.