另一个线程安全队列实现
Another thread safe queue implementation
我有一个 Queue
的类,我试图使线程安全。它具有这三个成员变量:
std::queue<T> m_queue;
pthread_mutex_t m_mutex;
pthread_cond_t m_condition;
和一个推动和弹出式实现为:
template<class T> void Queue<T>::push(T value)
{
pthread_mutex_lock( &m_mutex );
m_queue.push(value);
if( !m_queue.empty() )
{
pthread_cond_signal( &m_condition );
}
pthread_mutex_unlock( &m_mutex );
}
template<class T> bool Queue<T>::pop(T& value, bool block)
{
bool rtn = false;
pthread_mutex_lock( &m_mutex );
if( block )
{
while( m_queue.empty() )
{
pthread_cond_wait( &m_condition, &m_mutex );
}
}
if( !m_queue.empty() )
{
value = m_queue.front();
m_queue.pop();
rtn = true;
}
pthread_mutex_unlock( &m_mutex );
return rtn;
}
不幸的是,偶尔出现的问题可能是该代码的错。也就是说,有两个线程,有时线程1永远不会从 push()
出来,而其他时候线程2则永远不会从 pop()
出来( block
参数为 true
),尽管队列不是空的。
我了解还有其他可用的实现,但是如果需要,我想尝试修复此代码。有人看到任何问题吗?
构造函数具有适当的初始化:
Queue()
{
pthread_mutex_init( &m_mutex, NULL );
pthread_cond_init( &m_condition, NULL );
}
和destructor,相应的"销毁"呼叫。
如保罗·鲁贝尔(Paul Rubel)所述,您需要首先初始化静音。在这一点上,将MUTEX包装在可以处理您的初始化和最终确定的班级中可能是个好主意。例如:
class mutex {
private:
mutex(const mutex &m);
mutex &operator=(const mutex &m);
// OR inherit from boost::noncopyable
public:
mutex() {
pthread_mutex_init(&mut_, nullptr);
}
~mutex() {
pthread_mutex_destroy(&mut_);
}
pthread_mutex_t get() const { return mut_; }
private:
pthread_mutex_t mut_;
};
note是boost.threading库,其中包含写得很好的同步类。
您必须在使用之前初始化互斥x:pthread_mutex_init
//somewhere before push/pop
pthread_mutex_init(&m_mutex)
这完全与您的问题无关,但是您可以修复推送功能:
template<class T> void Queue<T>::push(T value)
{
pthread_mutex_lock( &m_mutex );
if( m_queue.empty() )
{
m_queue.push(value);
pthread_cond_signal( &m_condition );
}
else
{
m_queue.push(value);
}
pthread_mutex_unlock( &m_mutex );
}
我意识到测试ARM构建时发生的问题。解决方案是更新Pthreads库。随着更新的pthreads,一切都可以正常运行。
相关文章:
- 在c++队列中使用pop和visit实现线程安全
- C++数组队列实现方法错误
- 实现优先级队列
- 使用 std::forward_list 返回错误的队列实现
- 了解使用堆栈实现队列的递归调用机制
- ARM 上的无锁 SPSC 队列实现
- 如何实现唯一 id 队列,其中元素可以在 C++ 中"bumped"到顶部?
- 堆栈和队列的C++默认实现
- 实现循环阵列队列
- 为什么优先级队列是使用堆实现的,而我们可以更有效地使用向量来实现它
- 无锁队列实现中的虚假下溢C++
- 使用链表实现队列
- 无法在C++中实现队列<pair<int、int*> >
- 使用 BST 实现队列
- 根据堆栈类实现队列类的复制构造函数
- 从头开始实现队列结构 (C++)
- 用两个堆栈实现队列——脱队列测试问题
- 用链表实现队列
- 实现队列类,分段错误
- 使用 MFC 实现队列的正确方法