Qt SafeQueue 读写操作

源文件

#include "SafeQueue.h"

static int Max_Size=1<<31-1;

//使用QWaitCondition和QMutex可以实现比信号量更精确的控制
void CSafeQueue::enqueue(const qintptr &t)
{
    m_mutex.lock();
    m_nSize = m_queue.size();
    if( m_nSize == Max_Size )
    {
        m_bufferIsNotFull.wait(&m_mutex);//wait的过程:解锁->阻塞当前线程->wake唤醒->锁定->继续
    }
    m_queue.enqueue(t);
    qWarning() << "CSafeQueue::enqueue"<< m_queue.size();
    m_nSize = m_queue.size();
    emit(sizeChanged(m_nSize));
    m_mutex.unlock();
    m_bufferIsNotEmpty.wakeOne();
}

qintptr CSafeQueue::dequeue()
{
    m_mutex.lock();
    if (m_queue.empty())
    {
        m_mutex.unlock();
        return -1;
        m_bufferIsNotEmpty.wait(&m_mutex);//wait的过程:解锁->阻塞当前线程->wake唤醒->锁定->继续
    }
    qWarning() << "CSafeQueue::dequeue"<< m_queue.size();
    qintptr t = m_queue.dequeue();
    m_nSize = m_queue.size();
    emit(sizeChanged(m_nSize));
    m_mutex.unlock();
    m_bufferIsNotFull.wakeAll();
    return t;
}


/*
 * QMutex

QMutex类提供的是线程之间的访问顺序化。
QMutex的目的是保护一段代码,使得同一时间只有一个线程可以访问它。但在一个线程中调用lock(),其它线程将会在同一地点试图调用lock()时会被阻塞,直到这个线程调用unlock()之后其它线程才会获得这个锁。

QSemaphore
信号量QSemaphore可以理解为对互斥量QMutex功能的扩展,互斥量只能锁定一次而信号量可以获取多次,它可以用来保护一定数量的同种资源。acquire()函数用于获取n个资源,当没有足够的资源时调用者将被阻塞直到有足够的可用资源。release(n)函数用于释放n个资源。

#include 
#include 
#include 
#include 
#include 
using namespace std;
QSemaphore vacancy(5);       //空位资源
QSemaphore produce(0);       //产品数量
QMutex mutex;                //互斥锁
int buffer[5];               //缓冲区可以放5个产品
int numtaken=60;
int takei=0;
class Producer:public QThread
{
    public:
    void run();
};
void Producer::run()         //生产者线程
{
    for(int i=0;i<60;i++)    //生产60次产品
    {
        vacancy.acquire();   //P(s1)操作原语
        buffer[i%5]=i;
        printf("produced %d\n",i);
        produce.release();   //V(s2)操作原语
    }
}
class Consumer:public QThread
{
    public:
    void run();
};
void Consumer::run()         //消费者线程
{
    while(numtaken>1)
    {
        produce.acquire();   //P(s2)操作原语
        mutex.lock();        //从缓冲区取出一个产品...多个消费者,不能同时取出,故用了互斥锁
        printf("thread %ul take %d from buffer[%d] \n",currentThreadId(),buffer[takei%5],takei%5);
        takei++;
        numtaken--;
        mutex.unlock();
        vacancy.release();   //V(s1)操作原语
    }
}
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    Producer producer;
    Consumer consumerA;
    Consumer consumerB;
    producer.start();
    consumerA.start();
    consumerB.start();
    producer.wait();
    consumerA.wait();
    consumerB.wait();
    return 0;
}


*/

头文件

#ifndef SAFEQUEUE_H
#define SAFEQUEUE_H

#include 
#include 
#include 
#include 


/*使用QWaitCondition控制 一个生成者多个消费者的问题,写入控制,读取不控制 */
//template 
class CSafeQueue : public QObject
{
    Q_OBJECT
signals:
    void sizeChanged(int);
public:
    CSafeQueue(): m_nSize(0) {
    }

    int size(){return m_nSize;}

    void enqueue(const qintptr &t);

    qintptr dequeue();

private:
    QQueue m_queue;
    QMutex m_mutex;
    QWaitCondition m_bufferIsNotEmpty;
    QWaitCondition m_bufferIsNotFull;
    int m_nSize;
};

#endif // SAFEQUEUE_H

 

你可能感兴趣的:(Qt SafeQueue 读写操作)