multithreading - sistemas - Operaciones atómicas a prueba de hilos en gcc
que es la atomicidad en bases de datos (5)
AFAIK, no puede prefijar las instrucciones MOV con LOCK; esto solo está permitido para operaciones RMW. Pero si usa una tienda simple, también podría necesitar una barrera de memoria, que está implícita con mutex, así como también con instrucciones que permiten LOCK.
En un programa en el que trabajo, tengo un montón de código de la siguiente manera:
pthread_mutex_lock( &frame->mutex );
frame->variable = variable;
pthread_mutex_unlock( &frame->mutex );
Esto es claramente un desperdicio de ciclos de CPU si la instrucción del medio solo puede ser reemplazada con una tienda atómica. Sé que gcc es bastante capaz de esto, pero no he podido encontrar mucha documentación sobre operaciones atómicas simples tan seguras para subprocesos. ¿Cómo reemplazaría este conjunto de código con una operación atómica?
(Sé que las tiendas simples deberían ser teóricamente atómicas, pero no quiero esperar que el optimizador no esté atornillando su atomicidad en algún momento del proceso).
Aclaración: no necesito que sean estrictamente atómicos; estas variables solo se utilizan para la sincronización de subprocesos. Es decir, el subproceso B lee el valor, verifica si es correcto y, si no es correcto, duerme. Así que incluso si el hilo A actualiza el valor y el hilo B no se da cuenta de que está actualizado, eso no es un problema, ya que eso significa que el hilo B duerme cuando realmente no lo necesita, y cuando se despierta, el valor se correcto
Puede consultar la documentación de gcc. Para la versión actual de gcc (4.3.2) sería el capítulo 5.47 Funciones incorporadas para el acceso a la memoria atómica : para otras versiones de gcc, verifique sus documentos. Debería estar en el capítulo 5- Extensiones para la familia de lengua C.
Incidentalmente, el compilador de C no garantiza en absoluto que las operaciones simples de la tienda sean atómicas. No puedes confiar en esa suposición. Para que un código de operación de máquina se ejecute atómicamente, necesita el prefijo LOCK.
En x86 y en la mayoría de las otras arquitecturas, las lecturas y escrituras alineadas de 4 bytes son siempre atómicas. Sin embargo, el optimizador puede omitir / reordenar lecturas y escrituras dentro de un solo hilo.
Lo que desea hacer es informar al compilador que otros subprocesos pueden haber tocado esta ubicación de memoria. (Un efecto secundario de pthread_mutex_lock
es decirle al compilador que otros subprocesos pueden haber tocado alguna parte de la memoria.) Puede ver volatile
recomendados, pero esto no está en la especificación C, y GCC no interpreta los volatile
esa manera.
asm("" : "=m" (variable));
frame->variable = variable;
es un mecanismo específico de GCC para decir que "la variable
se ha escrito, vuelva a cargarla".
Como puedo ver, estás usando la plataforma gnu para el desarrollo, por lo que es seguro decir que glic proporciona un tipo de datos con capacidades atómicas, ''sig_atomic_t''
. Por lo tanto, este enfoque puede garantizarle operaciones atómicas a niveles de kernel. no niveles de gcc.
Hasta cierto punto, las operaciones atómicas en C se proporcionaron directamente desde las fuentes del kernel a través del encabezado atomic.h.
Sin embargo, tener encabezados kernel que se usen directamente en el código de espacio de usuario es una práctica muy mala, por lo que el archivo de encabezado atomic.h se eliminó hace algún tiempo. En cambio, ahora podemos hacer uso de los "Builtins atómicos de GCC", que son un enfoque mucho mejor y más confiable.
Hay una muy buena explicación proporcionada por Tudor Golubenco en su blog . Incluso proporciona un reemplazo directo para el archivo atomic.h inicial, en caso de que tenga algún código que lo necesite.
Lamentablemente, soy nuevo en , por lo que solo puedo usar un enlace en mis comentarios, así que revisa la publicación de Tudor y obtén información.