#c #qt
#c #qt
Вопрос:
У меня есть класс, который постоянно выполняет вызовы rest с использованием таймера, результат этих вызовов rest отправляется обратно в класс и обрабатывается впоследствии. Проблема в том, что если деструктор этого класса вызывается во время процесса обновления, это приводит к сбою. Я попытался решить эту проблему с помощью рекурсивного мьютекса;
private:
QTimer* m_Timer = nullptr;
std::recursive_mutex m_RecursiveMutex;
Размещение одного вызова блокировки для деструктора и try_lock запуск функции обновления;
Class::~Destructor()
{
std::lock_guard<std::recursive_mutex> lock(m_RecursiveMutex);
m_Timer->stop();
delete m_Timer;
}
void Class::UpdateSelf(GetInfoResponse res)
{
if (m_RecursiveMutex.try_lock())
{
... do stuff
}
}
Однако это, похоже, ничего не меняет, поскольку функция обновления по-прежнему вызывается и завершает работу программы, я понятия не имею, что я делаю не так, поэтому буду признателен за любой вклад.
Комментарии:
1. Действительно ли ваш код использует потоки? Я подозреваю, что вам было бы гораздо лучше попытаться понять причину первоначального сбоя, а не пытаться исправить ситуацию с помощью мьютекса. В качестве отступления, просто сделайте
m_Timer
aQTimer
, а не aQTimer *
— на самом деле нет необходимости в дополнительном усложнении управления распределением / удалением кучи.2. Тот факт, что ваш объект может быть вызван независимо от того, существует он или нет, говорит мне, что мьютекс здесь не проблема. Отладьте свой код и проанализируйте время жизни объекта. Почему он используется после того, как деструктор уже был вызван?
3. Похоже, что вы делаете неправильно, удаляя
Class
объект из потока A, в то время как поток B все еще потенциально может получить доступ кClass
объекту. Простое добавление мьютекса не решит эту проблему; вам нужно будет придумать способ гарантировать, что поток B больше не сможет получить доступ к объекту, прежде чем поток A удалит объект. Подход с большим молотком состоял бы в том, чтобы поток A сообщал потоку B о выходе, затем поток A вызывает wait() / join() для блокировки до тех пор, пока поток B фактически не завершится, затем поток A удаляет объект, затем (необязательно) поток A впоследствии порождает новый поток B.