2012-06-19 10 views
26

Sto usando C++ std::atomic_flag come una bandiera booleana atomica. Impostare il flag su true o false non è un problema, ma come interrogare lo stato corrente del flag senza impostarlo su un valore? So che esistono metodi "atomic_flag_clear" e "atomic_flag_set". Restituiscono lo stato precedente ma modificano anche lo stato corrente. C'è un modo per interrogare lo stato di flag senza modificarlo o devo usare full 'std::atomic<bool>'.C++ atomic_flag query state

+1

Sembrerebbe che il suo unico uso sia quello di acquisire un lucchetto. Potresti usare un 'std :: atomic_flag' come un blocco che potresti acquisire prima di accedere a una risorsa condivisa, ma se quella risorsa condivisa è solo un' bool', allora come hai detto, potresti anche usare 'std :: atomic '. _Modifica: _ o piuttosto std :: atomic_bool, visto come si sono dedicati al problema di specializzarne uno per te! – Rook

+5

Non è possibile conoscere lo stato corrente, a meno che non si usi la semantica acquisizione/rilascio corretta (ad esempio, provare a bloccarla con 'atomic_flag_set', e quindi fare solo cose se in realtà si è modificato il valore). Semplicemente leggerlo ti direbbe solo qual è il valore quando lo leggi, e potrebbe essere cambiato subito dopo. –

+0

@ Mike: è davvero importante? Sembra che tutti gli OP desiderino sia la capacità di eseguire una lettura atomica e avere qualche nozione di letture e scritture ordinate. – Rook

risposta

39

Non è possibile leggere il valore di std::atomic_flag senza impostarlo su true. Questo è di design. Non è una variabile booleana (abbiamo std::atomic<bool> per quello), ma un flag minimo che è garantito senza blocco su tutte le architetture che supportano C++ 11.

Su alcune piattaforme le uniche istruzioni atomiche sono istruzioni di scambio. Su tali piattaforme, std::atomic_flag::test_and_set() può essere implementato con exchange var,1 e clear() con exchange var,0, ma non esiste un'istruzione atomica per la lettura del valore.

Quindi, se si desidera leggere il valore senza modificarlo, è necessario std::atomic<bool>.

+0

volevo solo citare il tuo libro .... – haohaolee

+0

Cosa succede se voglio stampare solo il suo valore per scopi di debug, quindi non mi interessa davvero che * questa * lettura particolare sia atomica? Ora uso l'elemento '.__ val' per quello, ma dà errore in alcune versioni di gcc (giustamente quindi suppongo) – user1273684

+0

Non puoi leggere il valore di un' std :: atomic_flag' per qualsiasi scopo senza modificare esso. Se vuoi leggerlo (anche per il debug di printf), hai bisogno di 'std :: atomic ' –

12

Se si desidera utilizzare atomic_flag per determinare se un filo deve uscire, si può fare in questo modo:

inizializzazione:

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

ciclo Discussione:

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

Quando si vuoi uscire dal thread:

keep_running.clear(); 
Problemi correlati