È sicuro rimuovere volatile
dalla definizione di m_flag
qui? Se m_flag
non è volatile, cosa impedirebbe ai compilatori di ottimizzare le condizioni di questo ciclo: while (!m_flag) m_cv.wait(lock);
? Lo standard (post-C++ 11) specifica esplicitamente che tali ottimizzazioni sono proibite in questi casi?È sicuro rimuovere il C++ volatile qui?
#include <mutex>
#include <condition_variable>
#include <future>
#include <iostream>
using namespace std;
class foofoo
{
volatile bool m_flag;
mutex m_mutex;
condition_variable m_cv;
public:
void DoWork()
{
m_flag = false;
unique_lock<mutex> lock(m_mutex);
auto junk = async(std::launch::async, [this]()
{
{
unique_lock<mutex> lock(m_mutex);
m_flag = true;
}
m_cv.notify_one();
});
while (!m_flag) m_cv.wait(lock);
cout << "ququ" << endl;
}
};
int main()
{
foofoo f;
f.DoWork();
}
Grazie! Quindi, in altre parole, se il corpo del ciclo non cambia la condizione del ciclo, ma contiene un "punto" di sincronizzazione, per ottimizzarlo, un compilatore dovrebbe analizzare se la condizione del ciclo potrebbe essere influenzata da un "lato visibile" effetto "da un altro thread che può sincronizzarsi con lo stesso" punto "? In pratica, i compilatori probabilmente si arrenderebbero e non tenterebbero mai di ottimizzare tali loop di distanza? .. –
Intendo "ottimizzare le condizioni del loop". Mi sono appena reso conto che stavo dicendo "loop" ovunque, anche se ovviamente il loop sarebbe rimasto, basta trasformarlo in un loop infinito ... –
@MaxGalkin Finché non scrivi una corsa di dati, il compilatore deve garantire che i cambiamenti fatto da un thread che in precedenza ha rilasciato un mutex è visibile a un thread che successivamente acquisisce lo stesso mutex. Non sono sicuro se direi "mai tentare di", ma finché il codice è libero da gare di dati, non ci dovrebbero essere sorprese con un compilatore conforme. –