Это продолжение к Летучий в C ++ 11
В этом вопросе мне сказали, что следующий код демонстрирует неопределенное поведение в C ++ 11, что меня сильно смутило. Могу ли я прочитать какой-либо материал (возможно, разделы стандарта) о поведении volatile в C ++ 11?
Или кто-то может объяснить, в чем проблема?
#include <iostream>
#include <chrono>
#include <thread>
using namespace std;
volatile int notify;
void watcher()
{
this_thread::sleep_for(chrono::seconds(2));
notify = 1;
cout << "Notification sent." << endl;
}
int main()
{
thread(watcher).detach();
notify = 0;
while (!notify)
{
cout << "Waiting." << endl;
this_thread::sleep_for(chrono::seconds(1));
}
cout << "Notification received." << endl;
return 0;
}
Стандарт описывает модель памяти и, в частности, понятие «гонки данных» (раздел 1.10). Совершенно очевидно, что ваш код имеет гонку данных для переменной notify
и, следовательно, неопределенное поведение.
Чтобы решить проблему, либо охраняйте доступ к notify
с помощью блокировки, или сделать его атомарной переменной, такой как std::atomic<int>
,
Других решений пока нет …