Предположим, у вас есть класс Ressource
, который управляет каким-то ресурсом с использованием RAII небезопасным для потоков образом. В особенности Ressource::~Ressource()
- это метод, который нельзя запускать одновременно (для нескольких объектов).
Теперь ваш класс Manager
, который содержит только группу Ressource
, является полностью потокобезопасным. Любой вызов метода Ressource
заключен в окружающий std::lock_guard
. Все в вашем потокобезопасном мире идеально, кроме вашего dtor. Теоретически мы могли бы реализовать это как
Manager::~Manager() {
{
std::lock_guard<std::mutex> lock { m_mutex };
m_ressources.~std::vector<Ressource>();
}
}
Однако этот подход приведет к двойному уничтожению.
Я вижу два альтернативных подхода, которые могут работать:
Обернуть Ressource
в ThreadsafeRessource
. Это вводит много шаблонного кода, и если мы хотим синхронизировать несколько Ressource
одновременно (без постоянных блокировок), нам, вероятно, понадобится еще один класс для коллекций, интерфейс которого непростой.
Оборачивание любых Ressource
или их коллекций в std::unique_ptr
. Это позволяет нам управлять временем жизни вручную, но вводит еще одно косвенное обращение. Хотя это, вероятно, незначительно, но все равно оставляет неприятный вкус.
Как бы вы это решили?