Мне нужно разработать структуру данных, которая будет использоваться в многопоточной среде. Базовый API прост: вставка элемента, удаление элемента, извлечение элемента, проверка существования элемента. Реализация структуры использует неявную блокировку, чтобы гарантировать атомарность одного вызова API. После того, как я реализовал это, стало очевидно, что мне действительно нужна атомарность для нескольких вызовов API. Например, если вызывающей стороне необходимо проверить существование элемента перед попыткой вставить его, он не может сделать это атомарно, даже если каждый отдельный вызов API является атомарным:
if(!data_structure.exists(element)) {
data_structure.insert(element);
}
Пример несколько неуклюж, но суть в том, что мы больше не можем доверять результату вызова «exists» после возврата из атомарного контекста (сгенерированная сборка ясно показывает небольшую вероятность переключения контекста между двумя вызовами).
Что я в настоящее время имею в виду, чтобы решить эту проблему, так это раскрытие блокировки через общедоступный API структуры данных. Таким образом, клиентам придется явно блокировать вещи, но, по крайней мере, им не придется создавать свои собственные блокировки. Есть ли лучшее общеизвестное решение подобных проблем? И пока мы этим занимаемся, не могли бы вы посоветовать какую-нибудь хорошую литературу по потокобезопасному проектированию?
РЕДАКТИРОВАТЬ: у меня есть лучший пример. Предположим, что поиск элемента возвращает либо ссылку, либо указатель на сохраненный элемент, а не его копию. Как можно защитить вызывающую сторону, чтобы безопасно использовать этот указатель\ссылку после возврата вызова? Если вы считаете, что отсутствие возврата копий является проблемой, подумайте о глубоких копиях, то есть объектах, которые также должны копировать другие объекты, на которые они указывают внутри.
Спасибо.