我在Qt中构建一个相当复杂的应用程序,可以动态加载动态库并将它们作为线程运行,并且它们必须尽可能快地在彼此之间传递信息,所以我认为原子队列将是我最好的情况,所以这是AtomicQueue.hpp文件:
#ifndef ATOMICQUEUE_HPP #define ATOMICQUEUE_HPP #include <QAtomicPointer> // Used http://www.drdobbs.com/parallel/writing-lock-free-code-a-corrected-queue/210604448?pgno=2 // as reference template<class T> class AtomicQueue { struct QueueNode { QueueNode( const T& value ) : next( NULL ),data( value ) {} ~QueueNode() { if ( next ) delete next; } QueueNode *next; T data; }; public: AtomicQueue() { m_front = new QueueNode( T() ); m_tail.store( m_front ); m_divider.store( m_front ); } ~AtomicQueue() {} void push( const T& value ) { m_tail.load()->next = new QueueNode( value ); m_tail = m_tail.load()->next; // This moves the QueueNode into the atomic pointer,making it safe :) while( m_front != m_divider.load() ) { QueueNode *tmp = m_front; m_front = m_front->next; delete tmp; } } bool peek( T& result ) { if ( m_divider.load() != m_tail.load() ) { // Problem area QueueNode *next = m_divider.load()->next; if ( next ) { result = next->data; return true; } } return false; } bool pop( T& result ) { bool res = this->peek( result ); if ( res ) { m_divider = m_divider.load()->next; } return res; } private: QueueNode *m_front; QAtomicPointer<QueueNode> m_divider,m_tail; }; #endif // ATOMICQUEUE_HPP
我推动并弹出一个项目后队列中断,我无法弄清楚原因.我对原子风格的线程安全编程很陌生,所以我很可能不理解这一点的具体方面.在调试模式下运行时,当我执行result = next-> data时,我在bool AtomicQueue :: peek函数中得到一个SEGSEV段错误.
谁能指出我做错了什么?
更新:
所以我修复了问题,这是在我的QueueNode析构函数中.基本上当我删除一个节点时,它会尝试清理所有其他节点,然后给我一些不同的路由来修复它:
>在QueueNode中设置一个标志,告诉它不要删除所有 – >下一个节点
>在删除之前分离前节点
>允许AtomicQueue管理节点的清理
我选择了第三个选项,因为它在推送新节点的同时已经做了一些清理,所以这里是任何感兴趣的人的固定类:
#ifndef ATOMICQUEUE_HPP #define ATOMICQUEUE_HPP #include <QAtomicPointer> // Used http://www.drdobbs.com/parallel/writing-lock-free-code-a-corrected-queue/210604448?pgno=2 // as reference template<class T> class AtomicQueue { struct QueueNode { QueueNode( const T& value ) : next( NULL ),data( value ) {} ~QueueNode() { /*if ( next ) delete next;*/ } QueueNode *next; T data; }; public: AtomicQueue() { m_front = new QueueNode( T() ); m_tail.store( m_front ); m_divider.store( m_front ); } ~AtomicQueue() { QueueNode *node = m_front; while( node->next ) { QueueNode *n = node->next; delete node; node = n; } } void push( const T& value ) { m_tail.load()->next = new QueueNode( value ); m_tail = m_tail.load()->next; // This moves the QueueNode into the atomic pointer,m_tail; }; #endif // ATOMICQUEUE_HPP
解决方法
注意:一旦我在代码中找出问题,这只是从我的问题中复制而来.谢谢@ peter-k指出这没有正式得到答复.
所以我修复了问题,m_tail; }; #endif // ATOMICQUEUE_HPP