QT关于多线程生产者和消费者的问题(进程同步)

时间:2021-06-12 20:22:07
#include <QtCore/QCoreApplication>
#include <QWaitCondition>
#include <QThread>
#include <QMutex>
#include <iostream>

const int DataSize = 100;
const int BufferSize = 1;
char buffer[BufferSize];

QWaitCondition bufferIsNotFull;
QWaitCondition bufferIsNotEmpty;
QMutex mutex;
int usedSpace=0;

class Producer : public QThread
{
protected:
    void run()
    {
        for (int i = 0; i < DataSize; ++i)
        {
            mutex.lock();
            while (usedSpace == BufferSize)
            {
                bufferIsNotFull.wait(&mutex);
            }
            std::cerr<<"P";
            ++usedSpace;
            bufferIsNotEmpty.wakeAll();
            mutex.unlock();
        }
    }
};

class Consumer : public QThread
{
protected:
    void run()
    {
        for (int i = 0; i < DataSize; ++i)
        {
            mutex.lock();
            while (usedSpace == 0)
            {
                bufferIsNotEmpty.wait(&mutex);
            }
            std::cerr<<"C";
            --usedSpace;
            bufferIsNotFull.wakeAll();
            mutex.unlock();
        }
        std::cerr<<std::endl;
    }
};

int main(int argc, char *argv[])
{
   Producer producer;
   Consumer consumer;
   producer.start();
   consumer.start();
   producer.wait();
   consumer.wait();
return 0;
}


1.void QMutex::lock() 和void QMutex::unlock()

lock用于锁定一个对象,数据结构或代码段,相当于操作系统中的P操作

unlock则反过来,相当于操作系统中的V操作

2.QWaitCondition它允许线程在一定条件下唤醒其他线程。

bool QWaitCondition::wait(QReadWriteLock *lockedReadWriteLock, unsigned long time = ULONG_MAX)
一旦调用,会解除当前的lock,变成unlock状态,互斥资源等待其他线程改变它的值,直到达到某一条件,使得线程重新唤起。


代码的调用顺序,start以后线程启动,wait后调用消费者的run函数。满足while条件后调用wait函数,进入阻塞状态。解锁后调用生产者run,锁定usedSpace变量,然后执行改变usedSpace变量。调用wakeall唤醒所有线程(消费者线程)。之后又满足生产者while条件,执行wait函数,把生产者线程进入阻塞状态,解锁usedSpace变量。在循环

通过pv操作,和wait操作就完成了进程同步。