es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Es legal para el compilador asumir que una variable estática no será modificada por otro hilo?

Me sorprende un poco que el compilador (gcc) simplemente asuma que una variable estática nunca será modificada por otros hilos aunque se utilice el nivel de optimización más bajo. Estaba intentando leer un valor escrito desde otro hilo, pero gcc simplemente piensa que el valor nunca ha cambiado. ¿Es un comportamiento indefinido leer un valor de una variable estática que ha sido modificada por otro hilo según el estándar?

Específicamente estoy preguntando por la suposición que está haciendo el compilador. No estoy preguntando qué ocurre cuando un programa no maneja correctamente la sincronización de hilos.


Para aclarar a futuros lectores, solo la respuesta seleccionada responde claramente mi pregunta tal y como se plantea en el título. No resolvió el problema que tenía en realidad, pero eso es lo que pregunté. Aún así, me gustaría aclarar cuál era el problema real y cómo finalmente entendí lo que el compilador estaba haciendo.

Dada una variable global estática n,

static int n;

Puse n en un bucle para crear un bloqueo de giro con fallos.

while (!n); doSomething();

A menos que n sea volatile o _Atomic, el compilador simplemente asumirá que el valor de n no cambiará dentro del bucle.

Luego me di cuenta de que la parte del código que depende de un manejador de señal funcionaba como se esperaba.

n = 0; //añadido para explicación
sigset_t s;
sigemptyset(&s);
sigaddset(&s, SIGUSR1);
sigwait(&s, (int *)&_);
if (n) doSomething(); //el compilador sigue comprobando el valor de `n`

En un principio pensé que algo especial estaba ocurriendo con sigwait, pero eso no era cierto. Con este ejemplo más sencillo,

n = 0;
putchar(0);
if (n) doSomething();

el compilador aún no puede asumir que el valor de n es 0 porque putchar podría tener un efecto secundario modificando el valor de n, ya que n es una variable global.

Por supuesto, cualquier compilador sensato optimizará esto.

n = 0;
if (n) doSomething();

Después de todo, todo está funcionando bien con un buen manejador de señales.

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    La respuesta es sí, leer el valor de una variable estática modificada por otro hilo de ejecución es un comportamiento indefinido según el estándar de C. El compilador no está obligado a asumir nada sobre la variable estática y su acceso por parte de otros hilos de ejecución, y los niveles de optimización pueden afectar cómo el compilador genera código para dicho acceso.

    Sin embargo, es importante señalar que el problema aquí no tiene que ver con la sincronización de hilos de ejecución, sino más bien con las suposiciones y optimizaciones del compilador. Para garantizar un comportamiento multihilo correcto, se deben utilizar mecanismos de sincronización adecuados, como mutex y átomos.

Comments are closed.