Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/146.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 生产者和消费者在应用程序应该退出时无限期地等待_C++_Multithreading_Qt_Qt4 - Fatal编程技术网

C++ 生产者和消费者在应用程序应该退出时无限期地等待

C++ 生产者和消费者在应用程序应该退出时无限期地等待,c++,multithreading,qt,qt4,C++,Multithreading,Qt,Qt4,我使用QMutex对象、生产者线程的QWaitCondition对象和消费者线程的QWaitCondition对象实现了线程安全阻塞队列。函数enqueue()和dequeue()如下所示: void MyQueue::enqueue(const QString& s) { _mutex.lock(); while (_queue.size() == _maxSize) { _producer.wait(&_mutex); } _queue.enque

我使用
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()
    函数,则该生产者将无限期等待

  • 如何解决此问题?

    我认为处理终止的最简单方法是使用原子标志(您可以使用或)并让
    \u消费者等待。
    使用超时


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

    如果终止是唯一的问题,您可以通过在
    循环时添加另一个条件来检查:

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

    队列可以通过设置关闭标志的API进行扩充,然后唤醒可能仍在等待它的所有线程。

    想到的最简单方法是提供一个全局布尔值(
    exit\u now
    或其他)设置为
    true
    ,然后广播到两个条件变量以唤醒。他们醒来,检查布尔值,然后退出线程。

    有一个指示关机的状态,并在唤醒消费者或生产者后读取该状态。所有生产者停止后,唤醒所有消费者,直到队列为空且所有消费者停止。