2012-06-19 9 views
26

Estoy usando C++ std::atomic_flag como indicador booleano atómico. Establecer el indicador en verdadero o falso no es un problema, sino cómo consultar el estado actual del indicador sin establecerlo en algún valor. Sé que hay métodos 'atomic_flag_clear' y 'atomic_flag_set'. Devuelven el estado anterior pero también modifican el estado actual. ¿Hay alguna manera de consultar el estado de la bandera sin modificarlo o tengo que usar el pleno derecho 'std::atomic<bool>'.C++ estado de consulta atomic_flag

+1

Parece que su único uso es ser un medio para adquirir un candado. Podrías usar un 'std :: atomic_flag' como un bloqueo que podrías adquirir antes de acceder a un recurso compartido, pero si ese recurso compartido es solo un' bool' entonces como dijiste, también podrías usar 'std :: atomic '. _Editar: _ o más bien std :: atomic_bool, ¡ya que se han tomado la molestia de especializar uno para ti! – Rook

+5

No puede conocer el estado actual, a menos que use la semántica de adquisición/liberación correcta (es decir, intente bloquearlo con 'atomic_flag_set', y luego solo haga las cosas si realmente cambió el valor). Simplemente leerlo solo le diría cuál era el valor cuando lo leyó, y podría haber cambiado inmediatamente después. –

+0

@Mike: ¿eso realmente importa? Parece que todo lo que OP desea es la capacidad de realizar una lectura atómica y tener alguna noción de lecturas y escrituras ordenadas. – Rook

Respuesta

39

No puede leer el valor de std::atomic_flag sin establecerlo en true. Esto es por diseño. No es una variable booleana (tenemos std::atomic<bool> para eso), pero una bandera mínima que se garantiza libre de bloqueo en todas las arquitecturas que admiten C++ 11.

En algunas plataformas las únicas instrucciones atómicas son instrucciones de intercambio. En dichas plataformas, std::atomic_flag::test_and_set() se puede implementar con exchange var,1 y clear() con exchange var,0, pero no hay instrucciones atómicas para leer el valor.

Por lo tanto, si quiere leer el valor sin cambiarlo, entonces necesita std::atomic<bool>.

+0

solo quería citar su libro .... – haohaolee

+0

¿Qué pasa si solo quiero imprimir su valor para fines de depuración, así que realmente no me importa que * esta * lectura en particular sea atómica? Ahora uso el elemento '.__ val' para eso, pero da un error en algunas versiones de gcc (con razón, supongo) – user1273684

+0

No se puede leer legítimamente el valor de un' std :: atomic_flag' para ningún propósito sin modificar eso. Si quieres leerlo (incluso para la depuración de printf), necesitas 'std :: atomic ' –

12

Si desea utilizar atomic_flag para determinar si un hilo debe salir, puede hacerlo de esta manera:

inicialización:

std::atomic_flag keep_running = ATOMIC_FLAG_INIT; 
keep_running.test_and_set(); 

bucle del hilo:

while (keep_running.test_and_set()) { 
    // do thread stuff 
} 

Cuando quiere que el hilo salga:

keep_running.clear(); 
Cuestiones relacionadas