Есть кусок шареной памяти (128MB), куда часто ломятся разные процессы-читатели и читают случайные куски по 1-32 КБ. Есть один процесс «Master», которому раз в 10 сек надо обновить целиком 128 MB так, чтобы никакой читатель не прочитал полкилобайта фигни.
Решение: т.к. любой процесс-читатель могут убить админы в любой момент, глупо рассчитывать на то, что процесс обязательно добровольно отпустит некий мьютекс, размещённый в этой шареной памяти.
Предлагается такая фигня:
В шареной памяти есть атомарные INT-переменные: fence, num, lasttime.
fence: если 1, значит закрыто для читателей
num: число читателей, копошащихся сейчас
lasttime: время успешного захода последнего читателя
1. На входе читатель с помощью CAS пытается заинкрементить num, если было открыто (0 == fence).
2. Отметившись в num, читатель атомарно пишет текущее микросекундное время (CLOCK_MONOTONIC) в lasttime, если там лежит меньшее (СAS-ом). Если там лежит время <= текущего, то читатель ничего не делает.
3. Читатель с помощью CAS на выходе декрементит num обратно.
4. Если Master хочет сделать своё дело, он ставит fence = 1, затем бесконечно ждёт num == 0. Если в этом ожидании он замечает, что lasttime устарел на секунду от текущего времени, то Master считает что кто-то из читателей подох посреди пути и делает своё дело вероломно, записывая num = 0 и затем открывая fence = 0.
Взлетит? Может есть чё попроще? Есть решение, при котором всё это не нужно, но это уже другая тема. Интересуют заморочи. Т.е. допустим, авто-отпускающийся мьютекс нужен.