Variables estáticas y subprocesos (C)

5 minutos de lectura

avatar de usuario
dahui

Sé que declarar una variable estática dentro de una función en C significa que esta variable conserva su estado entre invocaciones de funciones. En el contexto de los subprocesos, ¿dará como resultado que la variable conserve su estado en varios subprocesos o que tenga un estado separado? entre cada hilo?

Aquí hay una pregunta de un examen en papel anterior que me cuesta responder:

La siguiente función C está destinada a ser utilizada para asignar identificadores únicos (UID) a sus llamadores:

get_uid() 
{
static int i = 0;
return i++;
}

Explique de qué manera get_uid() podría funcionar incorrectamente en un entorno en el que varios subprocesos lo llaman. Usando un escenario de ejemplo específico, brinde detalles específicos sobre por qué y cómo podría ocurrir tal comportamiento incorrecto.

Por el momento, asumo que cada subproceso tiene un estado separado para la variable, pero no estoy seguro de si eso es correcto o si la respuesta tiene más que ver con la falta de exclusión mutua. Si ese es el caso, ¿cómo podrían implementarse los semáforos en este ejemplo?

  • Su pregunta final, preguntó cómo pueden ser los semáforos implementado en este ejemplo. ¿Quieres preguntar cómo podría implementarse esto? usando semáforos?

    – WhozCraig

    7 de abril de 2013 a las 1:08


  • Si está utilizando gcc, una buena adición al estándar son las variables estáticas __thread. Son variables estáticas, pero locales para cada hilo. Lo encuentro especialmente útil para administrar conexiones locales de subprocesos a un servidor …

    – usuario1251840

    1 de septiembre de 2014 a las 12:06

Su suposición (los hilos tienen su propia copia) no es correcta. El principal problema con el código es cuando varios subprocesos llaman a esa función get_uid()hay un posible condición de carrera en cuanto a qué subprocesos se incrementa i y obtiene la identificación que puede no ser única.

  • Correcto, ¿entonces dos subprocesos que ingresan a la función al mismo tiempo incrementarán i dos veces y luego regresarán con el mismo valor?

    – dahui

    7 de abril de 2013 a las 1:11

  • Hay muchas otras posibilidades también. El incremento podría estar en proceso de ocurrir, y terminaría con lo que parecería un valor totalmente aleatorio en i.

    – kanielc

    1 de febrero de 2014 a las 0:48

avatar de usuario
jim balter

Todos los hilos de un proceso comparten el mismo espacio de direcciones. Ya que i es una variable estática, tiene una dirección fija. Su “estado” es solo el contenido de la memoria en esa dirección, que es compartida por todos los subprocesos.

el postfijo ++ El operador incrementa su argumento y produce el valor del argumento antes del incremento. El orden en que se realizan no está definido. Una posible implementación es

copy i to R1
copy R1 to R2
increment R2
copy R2 to i
return R1

Si se está ejecutando más de un subproceso, ambos pueden estar ejecutando estas instrucciones simultáneamente o intercaladas. Elabore usted mismo secuencias en las que se obtengan varios resultados. (Tenga en cuenta que cada subproceso tiene su propio estado de registro, incluso para los subprocesos que se ejecutan en la misma CPU, porque los registros se guardan y restauran cuando se cambian los subprocesos).

Una situación como esta en la que hay diferentes resultados dependiendo del orden indeterminista de las operaciones en diferentes subprocesos se denomina condición de carreraporque hay una “carrera” entre los diferentes subprocesos en cuanto a cuál realiza qué operación primero.

  • @ user2253489 Puede recompensar una buena respuesta con un voto a favor. Incluso puede cambiar su selección si le gusta lo suficiente.

    –Jim Balter

    7 de abril de 2013 a las 3:13

  • Tienes que amar a esos tipos que votan negativo sin explicación :/

    – dahui

    27 mayo 2016 a las 16:10

avatar de usuario
Stephane Rolland

No, si desea una variable cuyo valor depende del hilo en el que se usa, debe echar un vistazo a Almacenamiento local de subprocesos.

Una variable estática, puedes imaginarla realmente como una variable completamente global. Es realmente lo mismo. Entonces es compartido por todo el sistema que conoce su dirección.

EDITAR: también como un comentario lo recuerda, si mantiene esta implementación como una variable estática, las condiciones de carrera podrían hacer que el valor i se incrementa al mismo tiempo en varios subprocesos, lo que significa que no tiene idea del valor que devolverán las llamadas a funciones. En tales casos, debe proteger el acceso mediante los llamados objetos de sincronización como mutexes o secciones criticas.

  • El ejemplo de código también sufre actualizaciones no atómicas, lo que significa que varios subprocesos podrían resultar esencialmente en un solo incremento.

    – WhozCraig

    7 de abril de 2013 a las 1:04


Dado que esto parece tarea, responderé solo una parte de esto y es que cada hilo compartirá la misma copia de i. IOW, los hilos no obtienen sus propias copias. Te dejaré la parte de la exclusión mutua.

Cada subproceso compartirá la misma variable estática, que probablemente sea una variable global. El escenario en el que algunos subprocesos pueden tener un valor incorrecto es la condición de carrera (el incremento no se realiza en una sola ejecución, sino que se realiza en 3 instrucciones de ensamblaje, carga, incremento, almacenamiento). Lea aquí y el diagrama en el enlace lo explica bien.

Condición de carrera

avatar de usuario
Sam

Si está usando gcc, puede usar el integrado atómico funciones No estoy seguro de lo que está disponible para otros compiladores.

int get_uid() 
{
    static int i = 0;
    return __atomic_fetch_add(&i, 1, __ATOMIC_SEQ_CST);
}

Esto garantizará que más de un subproceso no pueda actuar sobre la variable a la vez.

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad