目标:实现两个生产者线程产生随机数,一个消费者线程处理产生的随机数。
实现:实现三个类,分别是消费者 Customer,生产者 Productor,工具类 UnblockQueue
UnblockQueue类 (线程安全队列,没数据的时候消费者线程等待)
UnblockQueue.h
#pragma once
#include <queue>
#include <mutex>
#include <condition_variable>
template <typename T>
class UnblockQueue {
public:
UnblockQueue()
:m_mutex(), m_cond(), m_queue(), m_unblock(false)
{
}
void Push(T item)
{
std::unique_lock<std::mutex> lock(m_mutex);
m_queue.push(item);
m_cond.notify_one();
}
T Pop()
{
std::unique_lock<std::mutex> lock(m_mutex);
while (m_queue.empty() && !m_unblock)
{
m_cond.wait(lock);
}
if (m_unblock)
{
m_unblock = false;
return nullptr;
}
auto item = m_queue.front();
m_queue.pop();
return item;
}
size_t Size()
{
std::lock_guard<std::mutex> lockerGurard(m_mutex);
return m_queue.size();
}
void UnblockOne()
{
m_unblock = true;
std::unique_lock<std::mutex> locker(m_mutex);
locker.unlock();
m_cond.notify_one();
}
private:
UnblockQueue(const UnblockQueue<T>& queue);
UnblockQueue& operator= (const UnblockQueue<T>& queue);
private:
std::queue<T> m_queue;
std::mutex m_mutex;
std::condition_variable m_cond;
bool m_unblock;
};
Cutomer类
comtomer.h
#pragma once
#include <QThread>
#include <QString>
#include "UnblockQueue.h"
class Customer:public QThread
{
public:
Customer(UnblockQueue<QString>* dataQueue);
~Customer();
void Stop();
virtual void run();
private:
UnblockQueue<QString>* m_queue;
bool m_stop;
};
comtomer.cpp
#include "Customer.h"
#include <QDebug>
Customer::Customer(UnblockQueue<QString>* dataQueue)
:m_stop(true), m_queue(nullptr)
{
m_queue = dataQueue;
}
Customer::~Customer()
{
}
void Customer::Stop()
{
m_stop = true;
m_queue->UnblockOne();
}
void Customer::run()
{
m_stop = false;
while (!m_stop)
{
QString item = m_queue->Pop();
qDebug() << item;
}
qDebug() << "customer out";
}
Productor类
Productor.h
#include "UnblockQueue.h"
class Productor : public QThread
{
public:
Productor(QString productName,UnblockQueue<QString>* queue);
~Productor();
protected:
virtual void run();
private:
bool m_stop;
UnblockQueue<QString>* m_queue;
QString m_productName;
};
Productor.cpp
#include "Productor.h"
#include <random>
Productor::Productor(QString productName, UnblockQueue<QString>* queue)
:m_stop(true), m_queue(nullptr)
{
m_productName = productName;
m_queue = queue;
}
Productor::~Productor()
{
}
void Productor::run()
{
int count = 0;
while (count < 10)
{
std::random_device rd;
QString item = QString("%1--%2").arg(m_productName).arg(QString::number(rd()));
m_queue->Push(item);
count++;
}
}
main.cpp
#include <QtCore/QCoreApplication>
#include "Productor.h"
#include "Customer.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
UnblockQueue<QString>* myqueue = new UnblockQueue<QString>();
Customer customer(myqueue);
Productor producter1("product1", myqueue);
Productor producter2("product2", myqueue);
customer.start();
producter1.start();
producter2.start();
QThread::msleep(3000);
customer.Stop();
customer.wait(2000);
if (customer.isRunning())
{
customer.terminate();
}
customer.wait();
return a.exec();
}