前面几篇文章已经介绍了互斥锁,条件变量,任务队列类的封装,可见:
学习记录(4.4)---面向对象TaskQueue任务队列类的封装
1、类图
还是给出整体类图,对于生产者和消费者继承了我之前封装的线程类,重写其中的run函数 ,生产者需要从任务队列中生产任务执行push函数,消费者需要从任务队列中消费任务执行pop函数。
直接开始!!!
2、生产者类的封装
#ifndef __PRODUCER_H
#define __PRODUCER_H
#include"Thread.h"
#include"TaskQueue.h"
#include<stdlib.h>
#include<time.h>
#include<stdio.h>
#include<iostream>
#include <unistd.h>
using std::cout;
using std::endl;
//生产者类,继承自Thread类
class Producer :public Thread
{
private:
//生产者需要知道任务队列的地址
TaskQueue &_taskQue;
public:
//构造函数
Producer(TaskQueue &taskQue)
:_taskQue(taskQue)
{
}
//析构函数
~Producer()
{
}
//重写run()函数
void run() override
{
//使用系统时间作为随机数种子
::srand(::clock());
int cnt = 20;
while (cnt--)
{
//生成一个随机数
int num = ::rand() %100;
//将随机数放入任务队列
_taskQue.push(num);
cout << "Producer creat num == " << num << endl;
//生产者每次生产完之后,休眠2秒
sleep(2);
}
}
};
#endif
3、消费者类的封装
#ifndef __CONSUMER_H
#define __CONSUMER_H
#include"Thread.h"
#include"TaskQueue.h"
#include<stdlib.h>
#include<time.h>
#include<stdio.h>
#include<iostream>
#include <unistd.h>
using std::cout;
using std::endl;
// 消费者类,继承自Thread类
class Consumer :public Thread
{
private:
// 任务队列的引用
TaskQueue &_taskQue;
public:
// 构造函数,传入任务队列的引用
Consumer(TaskQueue &taskQue)
:_taskQue(taskQue)
{
}
// 析构函数
~Consumer()
{
}
// 重写run()函数,实现消费者的具体逻辑
void run() override
{
int cnt = 20;
while (cnt--)
{
// 从任务队列中取出一个任务
int tmp = _taskQue.pop();
cout << "Consumer consume tmp == " << tmp << endl;
// 模拟耗时操作,休眠2秒
sleep(2);
}
}
};
#endif
4、测试代码Test.cc
#include"Producer.h"
#include"Consumer.h"
#include<iostream>
#include<memory>
using std::cout;
using std::endl;
using std::unique_ptr;
void test()
{
//创建一个任务队列,最大容量为10
TaskQueue taskQue(10);
//创建一个生产者和一个消费者
unique_ptr<Thread> pro(new Producer(taskQue));
unique_ptr<Thread> consu(new Consumer(taskQue));
//启动生产者和消费者线程
pro->start();
consu->start();
//等待生产者和消费者线程结束
pro->join();
consu->join();
}
int main(int argc, char **argv)
{
//运行测试函数
test();
return 0;
}
对于一些改进的思想, 比如RAII,禁止复制等可以自行扩展,到此我们的生产者和消费者模型的封装已经完成,如有不足,欢迎指正!!!