Qt 多线程同步之条件变量

1.QWaitCondition

QWaitCondition与QMutex结合,可以使一个线程在满足一定条件时通知其他多个线程,使它们及时作出响应,这样比只使用互斥量效率要高一些。

常用API

  • wait(QMutex *lockedMutex, unsigned long time = ULONG_MAX):解锁互斥量lockedMutex,并阻塞等待唤醒条件,被唤醒后锁定lockedMutex并退出函数。
  • wakeAll():唤醒所有处于等待状态的线程,线程唤醒的顺序不确定,由操作系统的调度策略决定。
  • wakeOne():唤醒一个处于等待状态的线程,唤醒哪个线程不确定,由操作系统的调度策略决定。

2.示例

生产者-消费者模型

#ifndef MYTHREAD_H
#define MYTHREAD_H

#include <QThread>
#include <QQueue>
#include <QMutex>
#include <QMutexLocker>
#include <QDebug>
#include <QWaitCondition>

static int data = 500;
static int maxSize = 10;
static QQueue<int> que;
static QMutex mutex;
static QWaitCondition bufferNotEmpty;
static QWaitCondition bufferNotFull;

class Producer : public QThread
{
    Q_OBJECT
public:
    explicit Producer(QThread *parent)
        :QThread(parent)
    {

    }

protected:
    void run()
    {
        for(int i=0;i<data;i++)
        {
            mutex.lock();
            if(que.size() == maxSize)
                bufferNotFull.wait(&mutex);

            que.enqueue(i);
            qDebug()<<"Producer produce: "<<QString::number(i);
            bufferNotEmpty.wakeAll();
            mutex.unlock();
            msleep(100);
        }
    }
};

class Customer : public QThread
{
    Q_OBJECT
public:
    explicit Customer(QThread *parent,int id)
        :QThread(parent)
        ,m_id(id)
    {

    }
protected:
    void run()
    {
        while(true)
        {
            mutex.lock();
            if(que.isEmpty())
                bufferNotEmpty.wait(&mutex);

            int num = que.dequeue();
            qDebug()<<"Customer"<<QString::number(m_id)<<" consume:"<<QString::number(num);
            bufferNotFull.wakeAll();
            mutex.unlock();
            msleep(1000);//消费者消费的慢
        }
    }

private:
    int m_id = 0;
};



#endif // MYTHREAD_H

 


版权声明:本文为wzz953200463原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。