Является ли блокировка и разблокировка 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), затем сам объект удаляет.