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