En mi caja de Linux, sig_atomic_t
es un simple viejo int
. Hacer ints
posee una cualidad atómica especial?
$ gcc -v
Using built-in specs.
Target: x86_64-linux-gnu
...
Thread model: posix
gcc version 4.3.2 (Debian 4.3.2-1.1)
$ echo '#include <signal.h>' | gcc -E - | grep atomic
typedef int __sig_atomic_t;
typedef __sig_atomic_t sig_atomic_t;
C99 sig_atomic_t
se ajusta sólo a una definición muy débil de “atomicidad”, porque C99 no tiene concepto de concurrencia, sólo interrumpibilidad. (C2011 agrega un modelo de concurrencia, y con él el _Atomic
tipos que hacen garantías más fuertes; sin embargo, AFAIK sig_atomic_t
no ha cambiado, ya que su razón de ser todavía hay comunicación con los manejadores de señales, no a través de subprocesos).
Esto es todo lo que dice C99 sobre sig_atomic_t
:
(§7.14 <signal.h>
párrafo 2) El tipo definido es sig_atomic_t
, que es el tipo entero (posiblemente calificado como volátil) de un objeto al que se puede acceder como una entidad atómica, incluso en presencia de interrupciones asíncronas. (§7.14 <signal.h>
Párrafo 2)
(§7.14p5) Si [a] la señal se produce de otra manera que no sea el resultado de llamar al abort
o raise
función, el comportamiento no está definido si el controlador de señal se refiere a cualquier objeto con duración de almacenamiento estático que no sea asignando un valor a un objeto declarado como volatile sig_atomic_t
.
(§7.18.3 Límites de otros tipos de enteros, párrafo 3) Si sig_atomic_t
(ver 7.14) se define como un tipo entero con signo, el valor de SIG_ATOMIC_MIN
no será mayor que −127 y el valor de SIG_ATOMIC_MAX
no será inferior a 127; de lo contrario, sig_atomic_t se define como un tipo entero sin signo, y el valor de SIG_ATOMIC_MIN
será 0 y el valor de SIG_ATOMIC_MAX
no será inferior a 255.
El término “entidad atómica” no se define en ninguna parte del estándar. Traduciendo de los estándares-ese, el intención es que la CPU puede actualizar completamente una variable de tipo sig_atomic_t
en la memoria (“duración de almacenamiento estático”) con una instrucción de máquina. Por lo tanto, en la máquina abstracta C99 sin concurrencia y precisamente interrumpible, es imposible que un controlador de señal observe una variable de tipo sig_atomic_t
a la mitad de una actualización. El lenguaje §7.18.3p3 permite que este tipo sea tan pequeño como char
si necesario. Tenga en cuenta por favor el ausencia completa de cualquier idioma relacionado con la coherencia entre procesadores.
Hay CPU reales que requieren más de una instrucción para escribir un valor mayor que char
a la memoria También hay CPU reales que requieren más de una instrucción para escribir valores más pequeño que una palabra de máquina (a menudo, pero no necesariamente, lo mismo que int
) a la memoria. El lenguaje en el manual de la biblioteca GNU C ahora es inexacto. Representa un deseo por parte de los autores originales de eliminar lo que vieron como una licencia innecesaria para que las implementaciones de C hicieran cosas raras que hacían la vida más difícil para los programadores de aplicaciones. Desafortunadamente, esa misma licencia es lo que hace posible tener C en algunas máquinas reales. Hay al menos un puerto Linux incorporado (al AVR) para el cual ninguno int
ni los punteros se pueden escribir en la memoria en una instrucción. (La gente está trabajando para hacer que el manual sea más preciso, ver, por ejemplo, http://sourceware.org/ml/libc-alpha/2012-02/msg00651.html — sig_atomic_t
Sin embargo, parece haberse perdido en ese.)
Ciertos tipos pueden requerir múltiples instrucciones para leer/escribir. int
type siempre se lee/escribe atómicamente.
Tipo de datos: sig_atomic_t
Este es un tipo de datos entero. A los objetos de este tipo siempre se accede de forma atómica.
En la práctica, puede suponer que int y otros tipos de enteros no más largos que int son atómicos. También puede suponer que los tipos de punteros son atómicos; eso es muy conveniente. Ambos son ciertos en todas las máquinas compatibles con la biblioteca GNU C y en todos los sistemas POSIX que conocemos.
Referencia
@chrisaycock: C? ¿No se aplicaría esto a cualquier idioma con acceso a
sig_atomic_t
variables? Podría haber usado con la misma facilidadg++
.– smcdow
7 de marzo de 2012 a las 18:55
los
sig_atomic_t
type es en realidad parte de la especificación C. También se encuentra en la especificación C++ (como la mayoría de las cosas), pero es más probable que obtenga buenas respuestas con una etiqueta C.-Dietrich Epp
07/03/2012 a las 19:31
C no garantiza eso. Las CPU específicas tienen garantías específicas para la atomicidad de ciertos tipos. En particular, las CPU modernas utilizadas en los sistemas de escritorio tienden a garantizar la atomicidad al menos para alineados.
int
s (es decir, datos del tamaño de una palabra de plataforma). Este no es necesariamente el caso de las CPU más antiguas o de las CPU utilizadas en sistemas integrados.– ninjalj
7 de marzo de 2012 a las 19:59