并发队列使用Qt是死锁
Concurrent Queue using Qt is deadlocking
我正在尝试创建一个Qt的并发线程结构的并发队列。
#ifndef CONCURRENTQUEUE_H
#define CONCURRENTQUEUE_H
#include <QMutex>
#include <QWaitCondition>
#include <queue>
template<typename Data>
class ConcurrentQueue
{
private:
std::queue<Data> the_queue;
QMutex the_mutex;
QWaitCondition the_condition_variable;
bool closed;
public:
void setClosed(bool state)
{
QMutexLocker locker(&the_mutex);
closed = state;
}
bool getClosed()
{
QMutexLocker locker(&the_mutex);
return closed;
}
void push(Data const& data)
{
QMutexLocker locker(&the_mutex);
the_queue.push(data);
the_condition_variable.wakeOne();
}
bool empty()
{
QMutexLocker locker(&the_mutex);
return the_queue.empty();
}
bool try_pop(Data& popped_value)
{
QMutexLocker locker(&the_mutex);
if(the_queue.empty())
{
return false;
}
popped_value = the_queue.front();
the_queue.pop();
return true;
}
void wait_and_pop(Data& popped_value)
{
QMutexLocker locker(&the_mutex);
while(the_queue.empty())
{
the_condition_variable.wait(&the_mutex);
}
popped_value = the_queue.front();
the_queue.pop();
the_condition_variable.wakeOne();
}
//created to allow for a limited queue size
void wait_and_push(Data const& data, const int max_size)
{
QMutexLocker locker(&the_mutex);
while(the_queue.size() >= max_size)
{
the_condition_variable.wait(&the_mutex);
}
the_queue.push(data);
the_condition_variable.wakeOne();
}
};
#endif // CONCURRENTQUEUE_H
我有我的生产者线程使用wait_and_push方法将数据推送到队列中,我一直试图让我的消费者使用try_pop
从队列中读取数据 while(!tiles->empty() || !tiles->getClosed())
{
if(!tiles->try_pop(tile))
continue;
//do stuff with the tile
}
然而,这有时会死锁。生产者将关闭的布尔值设置为一个标志,告诉消费者线程它已经完成了队列的加载。我的消费者只是用它来了解队列是否正在加载、仍在进行中或尚未启动。
生产者使用"wait_and_push"而不是使用正常的push的原因是因为我希望能够使线程阻塞,直到一些项目被处理,以避免消耗太多内存,并做不必要的磁盘I/o。
谁能告诉我哪里出了问题?你忘了添加
the_condition_variable.wakeOne();
in try_pop
.
如果有多个生产者/消费者访问您的队列,您应该为生产者和消费者单独设置一个QWaitCondition
,否则wakeOne
可能无法唤醒正确的线程。
如果有多个生产者/消费者,那么您应该有一个notFullCondvar
和一个notEmptyCondvar
。
-
try_pop
方法唤醒notFullCondvar
。 -
wait_and_pop
等待notEmptyCondvar
,唤醒notFullCondvar
。 -
push
方法唤醒notEmptyCondvar
。 -
wait_and_push
方法等待notFullCondvar
,唤醒notEmptyCondvar
。
相关文章:
- 获取日期异步信号安全吗?如果在信号处理程序中使用,它会导致死锁吗
- 如何在没有死锁和/或争用的情况下正确使用 std::mutex C++?
- 用C++中的std::condition_variable将线程置于死锁中会有风险吗
- 使用 std::async 时死锁,将来作为成员
- 如何调试读写器锁的死锁?
- 为什么在Visual Studio 2013上的std::this_thread::sleep_for上死锁
- localtime() 函数正在调用 ___lll_lock_wait_private(),这会使线程陷入死锁
- 如何重现 Boost 进程文档提示的死锁?
- 多线程Windows GUI应用程序中的死锁
- 为什么printf会导致与future.get的死锁,而cout则不会?
- C++中具有阻塞队列和障碍的死锁
- 死锁使用 std::mutex 来保护多个线程中的 cout
- 避免并发等待对象中的死锁
- 在VC++中从DLLMAIN内部调用D3D的CREATEDEVICE时,它会创建一个死锁(loaderlock?)。有没有办法克服这个问题?最终目标内
- 当用2个螺纹锁定时,将recursive_mutex死锁
- 如何在C++Qt程序中调试多线程死锁
- Qt:调用QEventLoop::exec后死锁
- Qt信号槽多线程死锁
- 并发队列使用Qt是死锁
- Qt - QLocalSocket信号槽不工作导致析构函数死锁