2-ndk学习之c++基础篇(06)

2020-03-12  本文已影响0人  ftd黑马

这篇文章写一下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的学习之路,如果有不对的地方,希望大家在评论区多多指正,共同学习,谢谢大家。

上一篇 下一篇

猜你喜欢

热点阅读