繁体   English   中英

另一个线程安全队列的实现

[英]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 );
    }

和析构函数,相应的“ destroy”调用。

如Paul Rubel所述,您需要首先初始化互斥锁。 此时,将互斥体包装在将为您处理初始化和终结处理的类中可能是一个好主意。 例如:

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_;
};

值得注意的是Boost.Threading库,其中包含编写良好的同步类。

您必须在使用互斥锁之前对其进行初始化: pthread_mutex_init

//somewhere before push/pop
pthread_mutex_init(&m_mutex)

这根本与您的问题无关,但是您可以修复push函数:

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库。 使用更新的pthread,一切运行正常。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM