Pregunta

Si los bloqueos se aseguran de que solo un hilo acceda a los datos bloqueados a la vez, ¿qué controla el acceso a las funciones de bloqueo?

Pensé que boost :: mutex :: scoped_lock debería estar al comienzo de cada una de mis funciones para que las variables locales no se modifiquen inesperadamente por otro hilo, ¿es correcto? ¿Qué sucede si dos hilos intentan adquirir el bloqueo en momentos muy cercanos? ¿No se corromperán las variables locales de la cerradura utilizadas internamente por el otro hilo?

Mi pregunta no es específica de impulso, pero probablemente la usaré a menos que recomiende otra.

¿Fue útil?

Solución

Tiene razón, al implementar bloqueos necesita alguna forma de garantizar que dos procesos no obtengan el bloqueo al mismo tiempo. Para hacer esto, debe usar una instrucción atómica, una que se garantiza que se complete sin interrupción. Una de esas instrucciones es test-and-set , una operación que obtendrá el estado de una variable booleana, configúrela como verdadera y devuelva el estado recuperado previamente.

Lo que esto hace es que esto le permite escribir código que prueba continuamente para ver si puede obtener el bloqueo. Suponga que x es una variable compartida entre hilos:

while(testandset(x));
// ...
// critical section
// this code can only be executed by once thread at a time
// ...
x = 0; // set x to 0, allow another process into critical section

Dado que los otros subprocesos prueban continuamente el bloqueo hasta que se dejan entrar en la sección crítica, esta es una forma muy ineficiente de garantizar la exclusión mutua. Sin embargo, utilizando este concepto simple, puede construir estructuras de control más complicadas como los semáforos que son mucho más eficientes (porque los procesos no se repiten, están durmiendo)

Otros consejos

Solo necesita tener acceso exclusivo a los datos compartidos. A menos que sean estáticos o estén en el montón, las variables locales dentro de las funciones tendrán diferentes instancias para diferentes subprocesos y no hay necesidad de preocuparse. Pero los datos compartidos (cosas a las que se accede a través de punteros, por ejemplo) deben bloquearse primero.

En cuanto a cómo funcionan las cerraduras, están cuidadosamente diseñadas para evitar condiciones de carrera y, a menudo, tienen soporte de nivel de hardware para garantizar la atomicidad. Es decir, hay algunas construcciones de lenguaje de máquina garantizadas para ser atómicas. Los semáforos (y mutexes) se pueden implementar a través de estos.

La explicación más simple es que los bloqueos, muy por debajo, se basan en una instrucción de hardware que se garantiza que es atómica y no puede chocar entre hilos.

Las variables locales ordinarias en una función ya son específicas de un hilo individual. Solo las estadísticas, los datos globales u otros datos a los que pueden acceder simultáneamente múltiples subprocesos deben tener bloqueos que lo protejan.

El mecanismo que opera el bloqueo controla el acceso a él.

Cualquier primitiva de bloqueo debe poder comunicar los cambios entre los procesadores, por lo que generalmente se implementa sobre las operaciones del bus, es decir, leer y escribir en la memoria. También debe estructurarse de manera que dos hilos que intenten afirmar que no corromperán su estado. No es fácil, pero por lo general puede confiar en que cualquier bloqueo implementado por el sistema operativo no se corromperá por múltiples hilos.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top