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唤醒不会释放当前锁。需要手动释放锁
网友评论