2013-03-10 8 views
6

Im usando Visual Studio 2012 e C++ 11. Non capisco perché questo non funziona:std :: thread C++. Più discussioni stessi dati

void client_loop(bool &run) 
{ 
    while (run); 
} 

int main() 
{ 
    bool running = true; 
    std::thread t(&client_loop,std::ref(running)); 

    running = false ; 
    t.join(); 
} 

In questo caso, l'anello di filo t non finisce mai, ma ho esplicitamente impostato running-false. run e running hanno la stessa posizione. Ho provato a impostare running come una singola variabile globale ma non succede nulla. Ho provato a passare anche un valore puntatore ma niente.

I thread utilizzano lo stesso heap. Io davvero non capisco. Qualcuno può aiutarmi?

+0

Il tuo programma termina troppo presto per osservare qualcosa di interessante. –

+0

no, ho dimenticato di scrivere in questo esempio "t.join()" .. :) –

+0

cosa succede se imposti 'running' come' volatile'? – didierc

risposta

11

tuo programma ha indefinito Comportamento, perché introduce una gara di dati sulla variabile running (un thread scrive, un altro thread legge).

è necessario utilizzare un mutex per sincronizzare l'accesso, o fare un runningatomic<bool>:

#include <iostream> 
#include <thread> 
#include <atomic> 

void client_loop(std::atomic<bool> const& run) 
{ 
    while (run.load()); 
} 

int main() 
{ 
    std::atomic<bool> running(true); 
    std::thread t(&client_loop,std::ref(running)); 

    running = false ; 
    t.join(); 

    std::cout << "Arrived"; 
} 

Consulta l'live example lavoro.

+0

grazie, io (stupidamente) pensavo che non fosse necessaria alcuna precauzione se il secondo thread leggesse solo i dati .. Non conoscevo la variabile "atomica": Ma ora che ho scoperto sono molto felice. grazie ancora –

+0

+1 Ho imparato qualcosa oggi. – didierc

+0

@MatteoGaleotti Potrebbe anche aver funzionato su architetture ragionevoli (sebbene sia ancora UB, ovviamente), se questo ciclo infinito non fosse stato così semplice da essere semplicemente ottimizzato. –

0

Il const probabilmente non influisce sulla visualizzazione del codice del compilatore. In un'applicazione a thread singolo, il valore non cambierà (e questo particolare programma non ha senso). In un'applicazione multi-thread, poiché è un tipo atomico, il compilatore non può ottimizzare il carico, quindi in effetti non c'è alcun problema reale qui. È davvero più una questione di stile; poiché main modifica il valore e client_loop cerca tale modifica, non mi sembra corretto affermare che il valore è const.