QWaitCondition BlockingQueue: уничтожено, пока потоки все еще ждут

Я построил свою собственную очередь блокировки в Qt, и у меня возникла небольшая проблема. Если я не закрываю очередь, я получаю сообщение об ошибке в консоли «QWaitCondition: Destroyed while threads are still waitingMsgstr «С другой стороны, я получаю исключение нарушения доступа после закрытия очереди (независимо от того, находится ли она в конструкторе или из другого потока). Исключение возникает в методе ожидания условия ожидания.

Вот моя очередь блокировки:

#ifndef BLOCKING_QUEUE_H
#define BLOCKING_QUEUE_H

#include <QObject>
#include <QSharedPointer>
#include <QWaitCondition>
#include <QMutex>
#include <queue>

namespace Concurrency
{
template<typename Data>
class BlockingQueue
{
private:
QMutex _mutex;
QWaitCondition _monitor;
volatile bool _closed;
std::queue<QSharedPointer<Data>> _queue;

public:
BlockingQueue()
{
_closed = false;
}

~BlockingQueue()
{
Close(); // When this is enabled, I get an access violation exception in TryDequeue
}

void Close()
{
QMutexLocker locker(&_mutex);
if(!_closed)
{
_closed = true;
_queue.empty();
_monitor.wakeAll();
}
}

bool Enqueue(QSharedPointer<Data> data)
{
QMutexLocker locker(&_mutex);

// Make sure that the queue is not closed
if(_closed)
{
return false;
}

_queue.push(data);

// Signal all the waiting threads
if(_queue.size()==1)
{
_monitor.wakeAll();
}

return true;
}

bool TryDequeue(QSharedPointer<Data>& value, unsigned long time = ULONG_MAX)
{
QMutexLocker locker(&_mutex);

// Block until something goes into the queue
// or until the queue is closed
while(_queue.empty())
{
if(_closed || !_monitor.wait(&_mutex, time)) // <-- Access violation if I call close in the destructor
{
return false;
}
}

// Dequeue the next item from the queue
value = _queue.front();
_queue.pop();
return true;
}
};
}
#endif BLOCKING_QUEUE_H

Я предполагаю, что это происходит потому, что ожидающий поток получает сигнал после того, как очередь уже уничтожена, а мьютекс также уничтожен. Когда нить просыпается в TryDequeueмьютекс больше не выделяется, поэтому он вызывает исключение нарушения прав доступа. Какой лучший способ избежать этого?

4

Решение

Проблема, с которой я столкнулся, была связана с многопоточным подходом, для получения дополнительной информации взгляните на этот вопрос: Почему сигнал QThread :: закончен, не излучается?

Сервис, который использовал BlockingQueue неправильно закрывал поток, который ожидал в очереди, и впоследствии вызывал разрушение очереди, пока поток все еще ожидает внутри TryDequeue метод.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]