Qt之线程同步

Qt中的线程同步

qt中实现了如下类,提供线程同步机制

  1. QMutex:互斥量。用来确保同一时刻,只能有一个线程访问某一资源。
  2. QReadWriteLock:读写锁。允许同一时刻多个线程读取某一资源,但只要有一个线程在写该资源,则不允许其他程同时读取该资源。
  3. QWaitCondition:等待条件。提供了一个条件变量同步线程,当某个条件满足时,可以发送信号通知其他线程该条件已经达到。
  4. QSemphone:信号量。能够保证同一时刻一个或多个资源不被并发访问,经常用在有限的相同资源条件下的线程同步。

线程同步之QMutex

Qt为我们提供了一系列的容器类,比如QList,QQueue,QStack等,但都是可重入(reentrant)而不是线程安全的(thread-safe)。因此当遇到多线程的容器共享时,我们就需要实现自己的线程安全版本容器,以QQueue为例:

   // QSafeQueue.h
    #include <QList>
    #include <QMutex>
    template<typename T>
    class QSafeQueue
    {
    public:
        QSafeQueue();
        void push_back(const T& data);
        T pop_front();
    private:
        QList<T> m_oList;
        QMutex m_oMutex;
    };

    // QSafeQueue.cpp  
    template<typename T>
    QSafeQueue<T>::QSafeQueue()
        : m_oList(),
        m_oMutex()
    {
    }

    template<typename T>
    void QSafeQueue<T>::push_back(const T &data)
    {
        m_oMutex.lock();
        m_oList.push_back(data);
        m_oMutex.unlock();
    }

    template<typename T>
    T QSafeQueue<T>::pop_front()
    {
        if (m_oList.empty())
            throw;
        m_oMutex.lock();
        T temp = m_oList.front();
        m_oList.pop_front();
        m_oMutex.unlock();
        return temp;
    }

针对上面的实现,考虑这样一种情况,假设队列很长,并且在某些时候从队列中读取数据的线程要远远多于向队列中添加数据,此时读线程的锁就会影响写线程,从而降低队列的执行效率,为此我们需要改进安全队列,使用读写两个不同的锁,看下列实现:

 // QSafeQueue.h
    #include <QList>
    #include <QMutex>
    template<typename T>
    class QSafeQueue
    {
    public:
        QSafeQueue();
        void push_back(const T& data);
        T pop_front();
    private:
        QList<T> m_oList;
        QMutex m_oReadMutex;
        QMutex m_oWriteMutex;
    };

    // QSafeQueue.cpp  
    template<typename T>
    QSafeQueue<T>::QSafeQueue()
        : m_oList(),
        m_oMutex()
    {
    }

    template<typename T>
    void QSafeQueue<T>::push_back(const T &data)
    {
        m_oWriteMutex.lock();
        m_oList.push_back(data);
        m_oWriteMutex.unlock();
    }

    template<typename T>
    T QSafeQueue<T>::pop_front()
    {
        if (m_oList.empty())
            throw;
        m_oReadMutex.lock();
        T temp = m_oList.front(
  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值