Я пишу программу, которая из соображений производительности использует разделяемую память (сокеты и каналы в качестве альтернатив были оценены, и они недостаточно быстры для моей задачи, вообще говоря, любой метод IPC, который включает в себя копии, слишком медленный). В области общей памяти я пишу много структур фиксированного размера. Существует одна программа, отвечающая за запись структур в общую память, и множество клиентов, которые читают из нее. Однако в каждой структуре есть один член, в который клиенты должны писать (счетчик ссылок, который они будут обновлять атомарно). Все остальные участники должны быть доступны только для клиентов.
Поскольку клиентам необходимо изменить этого одного члена, они не могут сопоставить область общей памяти только для чтения. Но они также не должны возиться с другими участниками, и, поскольку эти программы написаны на C ++, возможно повреждение памяти. В идеале, одному клиенту должно быть как можно сложнее разбить другого. Я беспокоюсь только о клиентах с ошибками, а не о вредоносных, поэтому допускаются несовершенные решения.
Я могу попытаться остановить перезапись клиентов, объявив элементы в заголовке, которые они используют как const, но это не предотвратит перезапись памяти (переполнение буфера, неправильное приведение и т. Д.). Я могу вставить канареек , но тогда мне придется постоянно оплачивать стоимость их проверки.
Вместо того, чтобы хранить элемент счетчика ссылок напрямую, я мог бы хранить указатель на фактические данные на отдельной отображенной странице только для записи, сохраняя структуры в отображаемых страницах только для чтения. Это будет работать, ОС вызовет сбой моего приложения, если я попытаюсь записать данные, на которые указывает указатель, но косвенное хранение может быть нежелательным при попытке написать алгоритмы без блокировки , потому что нужно следовать другому уровню косвенность может измениться, может ли что-то быть сделано атомарно.
Есть ли способ пометить меньшие области памяти так, что их запись приведет к взрыву вашего приложения? У некоторых платформ есть аппаратные точки наблюдения, и, возможно, я мог бы активировать одну из них со встроенной сборкой, но я бы ограничился только 4 на 32-битном x86 за раз, и каждая могла покрывать только часть структуры, потому что они ограничены до 4 байтов. Это также сделало бы мою программу болезненной для отладки;)
Редактировать: я нашел эту довольно сногсшибательную бумагу , но, к сожалению, она требует использования памяти ECC и модифицированного ядра Linux.