我已经使用QMutex对象,生产者线程的QWaitCondition对象和消费者线程的QWaitCondition对象实现了线程安全的阻塞队列。函数enqueue()dequeue()如下所示:

void MyQueue::enqueue(const QString& s)
{
    _mutex.lock();

    while (_queue.size() == _maxSize) { _producer.wait(&_mutex); }

    _queue.enqueue(s);
    _consumer.wakeAll();

    _mutex.unlock();
}

QString MyQueue::dequeue()
{
    QString s;

    _mutex.lock();

    while (_queue.empty()) { _consumer.wait(&_mutex); }

    s = _queue.dequeue();

    _producer.wakeAll();
    _mutex.unlock();

    return s;
}


需要访问此共享队列的使用者和生产者线程都有一个构造函数,该构造函数引用了MyQueue对象。上面的实现可以正常工作,但是当必须终止主程序时会出现问题,因为某些使用者或生产者会无限期地等待,尤其是:


如果队列为空,并且使用者已调用dequeue()函数,则该使用者将无限期等待。
如果队列已满,并且生产者已调用enqueue()函数,则该生产者将无限期等待。


我该如何解决这个问题?

最佳答案

我认为处理终止的最简单方法是使用原子标志(可以使用std::atomic_boolQAtomicInt)并让_consumer.wait使用超时。

当您detect a timeout(如果发生超时,wait返回false)时,检查是否cancel==true标志,然后退出,否则再次等待。因此,在最坏的情况下,它们将等待time毫秒然后退出。

关于c++ - 生产者和消费者无限期地等待何时退出应用程序,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24742126/

10-13 03:21