C++引用进阶和多线程

2022-08-21  本文已影响0人  大虾啊啊啊

1、引用进阶

class Student {
private:
    string name;
public:
    void setName(string name) {
        this->name = name;
    }

    string &getName() {
        return this->name;
    }

    string getName2() {
        return this->name;
    }
};
/**
 * 引用进阶
 * @return
 */
int main() {
    Student student;
    student.setName("xiaohong");
    cout << student.getName() << endl;
    //因为返回的是引用,所以会修改值
    student.getName() = "xiaoming";
    cout << student.getName() << endl;
    //因为返回的是非引用,只是值传递,所以不会修改值
    student.getName2() = "xiaowang";
    cout << student.getName() << endl;

    return 0;
}

xiaohong
xiaoming
xiaoming

在getName函数中,如果返回的是引用,可以直接通过赋值修改。如果返回的是值,则不能修改。

2、多线程pthread

启动一个线程

pthread_join函数为等待异步线程执行完毕

/**
 * 函数指针
 * @param value
 * @return
 */
void *run(void *value) {
    //通用类型指针转成 int类型指针
    int *number = static_cast<int*>(value);
    cout<<"异步线程启动了:"<<*number<<endl;
    return 0;
}
/**
 * void * 代表通用类型
 * @return
 */
int main() {
    int number = 888;
    pthread_t pthreadId;//线程ID
    //参数1 线程id
    //参数2 线程属性 传0即可
    //参数3 函数指针
    //参数4 给函数指针传值
    pthread_create(&pthreadId, 0, run, &number);
    pthread_join(pthreadId, 0);
    cout << "main 函数弹栈了" << endl;
}

异步线程启动了:888
main 函数弹栈了

c++中的互斥锁

(1)声明一个互斥锁
pthread_mutex_mutex
(2) 初始化互斥锁
pthread_mutex_init(&mutex, NULL);
(3)销毁互斥锁
pthread_mutex_destroy(&mutex);
(4)加锁
pthread_mutex_lock(&mutex);
(5)解锁
pthread_mutex_unlock(&mutex);

#include <iostream>

#include <vector>
#include <stack>
#include <queue> // 队列支持(内部:基本上 链表 、 数组 )
#include <list> // list容器的支持
#include <set>
#include <map>
#include <algorithm> // 算法包
#include <unistd.h> // sleep(秒)

using namespace std;

pthread_mutex_t mutex;//定义一个互斥锁(ygwin平台 此互斥锁,不能有野指针)
queue<int> queues;
/**
 * 函数指针
 * @param value
 * @return
 */
void *run(void *value) {
    //加锁
    pthread_mutex_lock(&mutex);
    //通用类型指针转成 int类型指针
    int *number = static_cast<int *>(value);
    if(queues.empty()){
        cout << "异步线程:" << *number <<"没有数据,加入数据,"<<*number<< endl;
        queues.push(*number);
    }
    else{
        int value = queues.front();
        queues.pop();
        cout << "异步线程:" << *number <<"有数据,取出数据,"<<value<<"并弹出数据"<< endl;
    }

    //解锁
    pthread_mutex_unlock(&mutex);
    return 0;
}

/**
 * void * 代表通用类型
 * @return
 */
int main() {
    //初始化互斥锁
    pthread_mutex_init(&mutex, NULL);
    //定义10个线程
    pthread_t pthreadIds[10];//线程ID
    //参数1 线程id
    //参数2 线程属性 传0即可
    //参数3 函数指针
    //参数4 给函数指针传值
    //  cout<<"开始启动第:"<<i<<"个线程"<<endl;
    int number = 100;
    int number1 = 101;
    int number2 = 102;
    int number3 = 103;
    int number4 = 104;
    pthread_create(&pthreadIds[0], 0, run, &number);
    pthread_create(&pthreadIds[1], 0, run, &number1);
    pthread_create(&pthreadIds[2], 0, run, &number2);
    pthread_create(&pthreadIds[3], 0, run, &number3);
    pthread_create(&pthreadIds[4], 0, run, &number4);
    //休眠20S
    sleep(20);
    cout << "main 函数弹栈了" << endl;
    //销毁互斥锁
    pthread_mutex_destroy(&mutex);
    return 0;
}

异步线程:100没有数据,加入数据,100
异步线程:101有数据,取出数据,100并弹出数据
异步线程:102没有数据,加入数据,102
异步线程:103有数据,取出数据,102并弹出数据
异步线程:104没有数据,加入数据,104
main 函数弹栈了

互斥锁+条件变量+等待唤醒+队列实现生产者消费者模式

//
// Created by DELL on 2022/9/6.
//

#ifndef JNI_05_VIDEOCHANNEL_H
#define JNI_05_VIDEOCHANNEL_H

#include <queue>
#include <pthread.h>
#include <android/log.h>
#include "SafeQueue.h"

using namespace std;
#define TAG "MainActivity_C"
// ... 我都不知道传入什么  借助JNI里面的宏来自动帮我填充
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__)

class VideoChannel {
private:


public:
    VideoChannel();

    /**
     * 插入数据
     */
    void insert();

    /**
     * 取出数据,并删除
     */
    void getAndDelete();

    /**
     * 队列
     */
    SafeQueue<int> queues;

    /**
     * 开启生产、消费者模式
     */
    void start();
};


#endif //JNI_05_VIDEOCHANNEL_H

//
// Created by DELL on 2022/9/6.
//

#include "VideoChannel.h"

VideoChannel::VideoChannel() {
}


void *add(void *object) {
    VideoChannel *channel = static_cast<VideoChannel *>(object);
    channel->insert();
    return nullptr;
}

void *get(void *object) {
    VideoChannel *channel = static_cast<VideoChannel *>(object);
    channel->getAndDelete();
    return nullptr;
}

/**
 * 添加
 */
void VideoChannel::insert() {
    while (true) {
        queues.insert(1);
        LOGD("插入的值是%d", 1);
    }
}
/**
 * 取出
 */
void VideoChannel::getAndDelete() {
    while (true) {
        int value = 0;
        queues.getAndDelete(value);
        LOGD("取出的值是%d", value);
    }


}
/**
 * 开启
 */
void VideoChannel::start() {
    pthread_t pid;
    pthread_t pid2;
    //
    pthread_create(&pid, nullptr, get, this);
    pthread_create(&pid2, nullptr, add, this);
}

//
// Created by DELL on 2022/9/7.
//

#ifndef JNI_05_SAFEQUEUE_H
#define JNI_05_SAFEQUEUE_H

#include <queue>
#include <pthread.h>
#include <android/log.h>
#include <unistd.h>

using namespace std;
#define TAG "MainActivity_C"
// ... 我都不知道传入什么  借助JNI里面的宏来自动帮我填充
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__)

template<typename T>
class SafeQueue {

private:
    queue<T> queue;
    pthread_mutex_t mutex;//定义一个互斥锁
    pthread_cond_t cond;//条件变量

public:
    SafeQueue() {
        //初始化互斥锁
        pthread_mutex_init(&mutex, NULL);
        // 初始化 条件变量
        pthread_cond_init(&cond, 0);
    }

    /**
     * 插入数据
     * @param t
     */
    void insert(T t) {
        //插入数据的时候先锁住
        pthread_mutex_lock(&mutex);
        if (!queue.empty()) {
            //等待
            pthread_cond_wait(&cond, &mutex);
        }
        queue.push(t);
        sleep(1);
        //唤醒
        pthread_cond_signal(&cond);
        //解锁
        pthread_mutex_unlock(&mutex);

    }

    /**
     * 取出数据
     * @param t
     * @return
     */
    void getAndDelete(T &t) {
        //取出数据的时候先锁住
        pthread_mutex_lock(&mutex);
        if (queue.empty()) {
            //等待
            pthread_cond_wait(&cond, &mutex);
        }
        //取出数据
        t = queue.front();
        //把这条数据弹出去
        queue.pop();
        sleep(1);
        //唤醒
        pthread_cond_signal(&cond);
        //解锁
        pthread_mutex_unlock(&mutex);


    }
};


#endif //JNI_05_SAFEQUEUE_H

2022-09-07 16:12:48.153 26935-27192/com.hvm.vender.jni_05 D/MainActivity_C: 插入的值是1
2022-09-07 16:12:49.154 26935-27191/com.hvm.vender.jni_05 D/MainActivity_C: 取出的值是1
2022-09-07 16:12:50.154 26935-27192/com.hvm.vender.jni_05 D/MainActivity_C: 插入的值是1
2022-09-07 16:12:51.154 26935-27191/com.hvm.vender.jni_05 D/MainActivity_C: 取出的值是1
2022-09-07 16:12:52.155 26935-27192/com.hvm.vender.jni_05 D/MainActivity_C: 插入的值是1
2022-09-07 16:12:53.155 26935-27191/com.hvm.vender.jni_05 D/MainActivity_C: 取出的值是1
2022-09-07 16:12:54.155 26935-27192/com.hvm.vender.jni_05 D/MainActivity_C: 插入的值是1
2022-09-07 16:12:55.156 26935-27191/com.hvm.vender.jni_05 D/MainActivity_C: 取出的值是1

结果得知调用pthread_cond_wait等待的时候,会释放当前锁,调用pthread_cond_signal唤醒不会释放当前锁。需要手动释放锁

上一篇 下一篇

猜你喜欢

热点阅读