这篇文章写一下c++经典案例,生产者消费者模式,我在代码中的注释写的很详细,这边就不多写了,干货哦!!!
工具类代码如下:
//
// Created by guow on 2020/3/12.
//
#ifndef CPPPROJECT_QUEUE_UTIL_H
#define CPPPROJECT_QUEUE_UTIL_H
#endif //CPPPROJECT_QUEUE_UTIL_H
#pragma once
#include <iostream>
#include <queue>
#include <string>
using namespace std;
//1.首先定义一个模板
template <typename T>
class SafeQueueClass{
private:
queue<T> queue1; //定义队列
pthread_mutex_t mutex1;//定义互斥锁,为了线程安全处理(不允许有野指针,所以在构造函数中需要初始化)
//定义一个条件变量,为了实现等待 读取的功能,类似于java中的wait,notify(同样也是不允许有野指针)
pthread_cond_t cond;
public:
SafeQueueClass(){
//初始化互斥锁
pthread_mutex_init(&mutex1,0);
//初始化条件变量
pthread_cond_init(&cond,0);
}
//在析构函数中进行回收操作
~SafeQueueClass(){
//回收互斥锁
pthread_mutex_destroy(&mutex1);
//回收条件变量
pthread_cond_destroy(&cond);
}
/**
* 生产者(把数据加入队列中)
* @param t
*/
void add(T t){
//为了保证同步的安全性,所以一进来就先锁上
pthread_mutex_lock(&mutex1);
queue1.push(t);
//添加上要唤醒消费者中的等待模式,否则消费者一直在等待
// pthread_cond_signal(&cond);//由系统去唤醒一个线程,类似于java的notify
pthread_cond_broadcast(&cond);//唤醒通知所有线程,类似于java的notifyAll
//同时函数执行完要释放锁
pthread_mutex_unlock(&mutex1);
}
/**
* 消费者,从队列中获取数据
*/
void get(T& t){//这里是c++独有的引用类型,不清楚的可以看我之前的文章有介绍过引用类型,引用可以把值传出去
//为了保证同步的安全性,所以一进来就先锁上
pthread_mutex_lock(&mutex1);
//这里不能使用if,如果使用if,线程可能会被系统唤醒,就往下执行了肯定有问题
while (queue1.empty()){
//条件变量用来等待,如果队列是空的说明还没有生产,所以消费者要等待
pthread_cond_wait(&cond,&mutex1);
}
//程序走到这里说明队列有数据了,可以进行消费了
t = queue1.front();
queue1.pop();//把数据从队列删除
//同时函数执行完要释放锁
pthread_mutex_unlock(&mutex1);
}
};
在main函数调用如下:
//
// Created by guow on 2020/3/12.
//
#pragma once
#include <iostream>
#include "main.h"
#include "mylog.h"
#include <queue>
#include <pthread.h>
#include <string>
#include "queue_util.h"
using namespace std;
SafeQueueClass<int> sq;
//消费者
void * getMethod(void * pVoid) {
while(9) {
LOGD("getMethod\n");
int value;
sq.get(value);
LOGD("消费者get 得到的数据:%d\n", value);
// 你只要输入 -1 就结束当前循环
if (-1 == value) {
LOGD("消费者get 全部执行完毕...");
break;
}
}
//这里必须return,否则会出现问题
return 0;
}
// 生产者
void * addMethod(void * pVoid) {
while (9) {
LOGD("setMethod\n");
int value;
LOGD("请输入您要的信息....\n");
cin >> value;
// 你只要输入 -1 就结束当前循环
if (-1 == value) {
sq.add(value); // 这里添加是为了,让消费者,可以获得-1,进行停止
LOGD("生产者set 全部执行完毕...");
break;
}
sq.add(value);
}
return 0;
}
int main() {
pthread_t pthread_add;
pthread_create(&pthread_add,0,addMethod,0);
pthread_t pthread_get;
pthread_create(&pthread_get,0,getMethod,0);
pthread_join(pthread_add,0);
pthread_join(pthread_get,0);
return 0;
}
至此,c++的学习之路先告一段落,后续开始jni的学习之路,如果有不对的地方,希望大家在评论区多多指正,共同学习,谢谢大家。
网友评论