生产者和消费者无限期地等待应用程序何时退出
Producers and consumers waiting indefinitely when the application should exit
我实现了一个线程安全的阻塞队列,使用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_bool或QAtomicInt)并让_consumer.wait
使用超时。
当您检测到超时时(如果发生超时,wait
返回false
),如果cancel==true
则检查标志,然后退出,否则再次等待。因此在最坏的情况下,它们将等待time
毫秒,然后退出。
如果终止是唯一的问题,您可以通过在while
循环中添加另一个检查条件来解决这个问题:
while (_queue.size() == _maxSize) {
_producer.wait(&_mutex);
if (_queue.shutting_down()) return;
}
这个队列可以通过一个API来增强,该API将设置关闭标志,然后唤醒任何可能仍在等待它的线程。
想到的最简单的方法是提供一个全局布尔值(exit_now
或其他东西),您将其设置为true
,然后广播到两个条件变量以唤醒。它们醒来,检查布尔值,然后退出线程。
相关文章:
- 试图在visual studio上用C++创建一个桌面应用程序
- FFmpeg:制作一个应用程序比直接使用ffmepg更好吗
- 在C应用程序中运行C++(带有STL)函数
- 使用VerQueryValue检索应用程序的文件描述
- Qt C++静态thread_local QNetworkAccessManager是线程应用程序的好选择吗
- 使用调试/崩溃报告将应用程序部署到客户端
- C++控制台应用程序阻止退出
- 码头化的C++应用程序是否向后兼容早期的内核版本
- 将应用程序从32位移植到64位时出现问题
- 如何改变c++应用程序的视觉效果
- WM_CTLCOLORSTATIC从未在WIN32应用程序中触发
- PC中的程序和PHONE中的本机描述应用程序之间的数据连接
- 应用程序崩溃并显示"symbol _ZdlPvm, version Qt_5 not defined in file libQt5Core.so.5 with link time reference"
- VCL 应用程序何时获取其应用程序>主窗体>句柄?
- 何时调用 Windows 控制台应用程序需要 CoInitialize
- 应用程序的建模.何时使用哪个图表
- 有什么方法可以判断分叉/执行Qt应用程序的主窗口何时显示?
- 生产者和消费者无限期地等待应用程序何时退出
- 检测应用程序何时在Windows中被卸载
- 何时在 c++ 应用程序中使用虚拟析构函数