Как синхронизировать во время деструктора - PullRequest
0 голосов
/ 13 июля 2020

Предположим, у вас есть класс 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>();
   }
}

Однако этот подход приведет к двойному уничтожению.

Я вижу два альтернативных подхода, которые могут работать:

  1. Обернуть Ressource в ThreadsafeRessource. Это вводит много шаблонного кода, и если мы хотим синхронизировать несколько Ressource одновременно (без постоянных блокировок), нам, вероятно, понадобится еще один класс для коллекций, интерфейс которого непростой.

  2. Оборачивание любых Ressource или их коллекций в std::unique_ptr. Это позволяет нам управлять временем жизни вручную, но вводит еще одно косвенное обращение. Хотя это, вероятно, незначительно, но все равно оставляет неприятный вкус.

Как бы вы это решили?

...