Одиночная запись - совместное использование буфера большой памяти без блокировок
Давайте предположим, что в качестве кадрового буфера используется большой буфер памяти, который постоянно записывается потоком (или даже несколькими потоками, гарантируя, что никакие два потока не будут одновременно писать один и тот же байт). Эти записи являются неопределенными во времени, разбросаны по базе кода и не могут быть заблокированы.
У меня есть еще один отдельный поток, который периодически считывает (копирует) весь буфер для создания кадра дисплея. Это чтение не должно быть заблокировано тоже. Разрыв не является проблемой в моем случае. Другими словами, моя единственная цель состоит в том, чтобы каждое изменение, сделанное потоком (ами) записи, в конечном итоге появлялось в потоке чтения. Порядок или некоторая (незначительная по сравнению с частотой обновления дисплея) задержка не имеет значения.
Одновременное чтение и запись одной и той же области памяти - это гонка данных, которая приводит к неопределенному поведению в C++11, и в этой статье перечислены те же самые ужасные примеры, когда оптимизирующий компилятор генерирует код для чтения из памяти, который изменяет содержимое памяти в наличие данных гонки.
Тем не менее, мне нужно какое-то решение без полной переделки этого унаследованного кода. Каждый совет считает, что является безопасным с практической точки зрения, независимо от того, является ли он теоретически правильным или нет. Я также открыт для не полностью переносимых решений.
Помимо того, что у меня есть гонка данных, я легко могу заставить видимость изменений буфера в потоке чтения, установив отношение между синхронизированными потоками (получить-освободить переменную атомарного защитного элемента, использованную ни для чего другого), или с помощью добавление платформо-зависимых вызовов памяти к ключевым точкам в потоке писателя.
Мои идеи нацеливаться на гонку данных:
Используйте сборку для чтения темы. Я бы постарался избежать этого.
Сделайте буфер памяти энергозависимым, что не позволит компилятору оптимизировать такие неприятные вещи, которые описаны в ссылочной статье.
Поместите код потока чтения в отдельный модуль компиляции и скомпилируйте с -O0
+1. Оставьте все как есть и скрестите пальцы (так как на данный момент проблем не замечаю):)
Что является самым безопасным из списка выше? Вы видите лучшее решение?
К вашему сведению, целевой платформой является ARM (с несколькими ядрами) и x86 (для тестирования).
(Этот вопрос конкретизирует предыдущий вопрос, который был слишком общим.)