Является ли блокировка и разблокировка CriticalSection в Destructor правильным способом?

class MyClass
{
   ...
   ...
   CCriticalSection m_Cs;

   void MyFunction()
   {
      m_Cs.Lock();

      .....

      m_Cs.Unlock(); 


   }

   MyClass::~MyClass()
   {
     ....

   }
};

Я использую критический раздел в своем классе, как указано выше, myFunction вызывается потоком 1, а когда myFunction выполняется, поток 2 удаляет объект. Так что Unlock рушится.

Поэтому я решил изменить деструктор MyClass, как показано ниже

 MyClass::~MyClass()
  {

     m_Cs.Lock();
     m_Cs.Unlock(); 
     ....

  }

Это разрешает мой сбой, потому что, когда поток 1 обращается к MyFunction, Critical Section блокируется, поэтому, когда объект удаляется из потока 2, CriticalSection.Lock в Destructor блокируется до тех пор, пока не будет вызвана разблокировка из MyFunction. Это правильное поведение, чтобы заблокировать и разблокировать Critical Section от деструктора, чтобы избежать этого сбоя?

1 ответ

Решение

Нет, это неправильный подход, поскольку он не защищает сценарий, в котором поток 2 удаляет объект, прежде чем поток 1 вызовет MyFunction.

В настоящее время в вашем коде есть ошибка Dangling Pointer.

Правильным решением является изменение вашего кода, чтобы гарантировать, что удаление объекта происходит в то время, когда никакой другой поток не может его использовать. Общие подходы к этому включают в себя:

  • Используйте события, чтобы сигнализировать, когда потоки завершены с использованием объекта, поток, который выполняет удаление, будет блокировать ожидание того, что все скажут, что они сделали.
  • Используйте подсчет ссылок. Пусть каждый поток, использующий объект, "приобретет" и "освободит" объект. Последний, который освобождает его (например, когда счетчик ссылок достигает 0), затем сам объект удаляет.
Другие вопросы по тегам