мне нужно очень быстро (в смысле «низкой стоимости для читателя», а не «низкая задержка») механизм уведомлений об изменениях между потоками для обновления кэша чтения:Нужен ли мне барьер памяти для флага уведомления об изменении между потоками?
Ситуация
тему W
(Writer) обновляет структуру данных (S
) (в моем случае настройку на карте) только один раз в то время.
Тема R
(Reader) хранит кэш S
и читает это очень часто. Когда Thread W
Обновления S
Тема сообщения R
необходимо уведомить об этом в разумные сроки (10-100 мс).
Архитектура ARM, x86 и x86_64. Мне нужно поддерживать C++03
с gcc 4.6 и выше.
Код
что-то вроде этого:
// variables shared between threads
bool updateAvailable;
SomeMutex dataMutex;
std::string myData;
// variables used only in Thread R
std::string myDataCache;
// Thread W
SomeMutex.Lock();
myData = "newData";
updateAvailable = true;
SomeMutex.Unlock();
// Thread R
if(updateAvailable)
{
SomeMutex.Lock();
myDataCache = myData;
updateAvailable = false;
SomeMutex.Unlock();
}
doSomethingWith(myDataCache);
Мой вопрос
В Thread R
не запирающего или барьеры возникают в "быстром пути" (нет доступных обновлений) , Это ошибка? Каковы последствия этого проекта?
Нужно ли квалифицировать updateAvailable
как volatile
?
Will R
Получить обновление В конечном итоге?
Мое понимание до сих пор
Безопасно в отношении целостности данных?
Это немного напоминает «Double Checked Locking». Согласно http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html, для исправления на C++ может использоваться барьер памяти.
Однако основное различие заключается в том, что общий ресурс никогда не затрагивается/читается на быстром пути чтения. При обновлении кеша консистенция гарантируется мьютексом.
Будет ли R
получить обновление?
Вот где это становится сложно. Как я понимаю, процессор, работающий с потоком R
, может кэшировать updateAvailable
неопределенно, эффективно перемещая путь чтения до фактического if
.
Таким образом, обновление может занять до следующего кэша, например, когда запланирован другой поток или процесс.
PS: Я знаю о http://stackoverflow.com/questions/8517969/is-this-the-correct-way-to-atomically-read-and-write-a-bool –
Код имеет неопределенное поведение, период. Добавление 'volatile' не меняет этого. –
Можете ли вы уточнить? Единственный способ увидеть, где он неопределен, - это то, что ЦП не надежно распространяет хранилище на другие ядра. 'volatile' должен гарантировать, что компилятор фактически выдает хранилище на адрес памяти (независимо от того, что ЦПУ решает сделать с этим - это еще одна вещь ... - он может быть сохранен в очереди на запись, в кеше или что-то еще до достижения основной памяти) –