c++ multithreading concurrency c++11 atomicity

c++ - std:: atomic<int> decremento y comparación



multithreading concurrency (3)

En el siguiente código:

std::atomic<int> myint; //Shared variable //(...) if( --myint == 0) { //Code block B }

¿Es posible que más de un hilo acceda al bloque que llamé "Bloque de código B"?

Tenga en cuenta que el desbordamiento no ocurrirá, que el ''si'' se está ejecutando al mismo tiempo por más de un hilo, que la única modificación de myint en todo el programa es --myint dentro de si myint se inicializa con un valor positivo .


C ++ 0x papel N2427 ( atómico ) indica aproximadamente lo siguiente. Cambié ligeramente la redacción, así que es más fácil de leer para la situación de disminución específica, las partes que cambié están en negrita :

Efectos: reemplazar atómicamente el valor en el objeto con el resultado de la disminución aplicada al valor en el objeto y el operando dado. La memoria se ve afectada según el orden. Estas operaciones son operaciones de lectura, modificación y escritura en el sentido de la definición "sincroniza con" en [la nueva sección añadida por N2334 o sucesora], y por lo tanto tanto dicha operación como la evaluación que produjo el valor de entrada se sincronizan con cualquier evaluación que lee el valor actualizado.

Devuelve: Atomicamente, el valor del objeto inmediatamente antes del decremento .

La operación atómica garantiza que el operador de decremento devolverá el valor que la variable tenía inmediatamente antes de la operación, esto es atómico, por lo que no puede haber ningún valor intermedio a partir de las actualizaciones de otro subproceso.

Esto significa que las siguientes son las únicas ejecuciones posibles de este código con 2 hilos:

(Initial Value: 1) Thread 1: Decrement Thread 1: Compare, value is 0, enter region of interest Thread 2: Decrement Thread 2: Compare, value is -1, don''t enter region

o

(Initial Value: 1) Thread 1: Decrement Thread 2: Decrement Thread 1: Compare, value is 0, enter region of interest Thread 2: Compare, value is -1, don''t enter region

El caso 1 es el caso esperado poco interesante.

El caso 2 intercala las operaciones de disminución y ejecuta las operaciones de comparación más adelante. Como la operación de disminución y recuperación es atómica , es imposible que el subproceso 1 reciba un valor distinto de 0 para la comparación. No puede recibir un -1 porque la operación fue atómica ... la lectura tiene lugar en el momento de la disminución y no en el momento de la comparación. Más hilos no cambiarán este comportamiento.


No es obvio que el bloque de código siempre se ejecutará. Si el operador "-" se implementa de tal manera que almacena el valor anterior en su valor de retorno y disminuye en una sola instrucción atómica (estoy bastante seguro de que x86 tiene tales instrucciones), entonces sí, debería actuar como un bloque de exclusión mutua para múltiples hilos. No estoy seguro de cómo funciona por defecto, pero la respuesta probablemente se encuentre en la nueva documentación estándar:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2427.html


No, no es posible que más de un hilo entre en el bloque, dadas tus limitaciones. Pero tampoco se garantiza que ningún hilo entre en este bloque:

thread A: decrement myint to 0 thread B: decrement myint to -1 thread A: compare to 0 -> false -> don''t enter (and neither anyone else)

Si esto es un problema (que supongo), este código no funcionará (al menos no siempre ).