目录
1--创建并等待多个线程
2--数据共享
2-1--数据只读
2-2--数据读写
2-3--共享数据保护简单案例
1--创建并等待多个线程
创建多个线程时,可以使用同一个线程入口函数;
多个线程的执行顺序与操作系统的调度机制有关,并不和创建线程的先后顺序相同;
一般会将多个线程对象存放在容器中,方便进行管理;
#include <iostream>
#include <thread>
#include <vector>
// 线程入口函数
void myprint(int i){
std::cout << "This is thread " << i << std::endl;
}
int main(int argc, char *argv[]){
std::vector<std::thread> V;
// 创建5个线程
for(int i = 0; i < 5; i++){
V.push_back(std::thread(myprint, i));
}
// 等待5个线程
for(auto iter = V.begin(); iter != V.end(); iter++){
iter->join();
}
// 继续执行主线程
std::cout << "This is main thread." << std::endl;
return 0;
}
2--数据共享
2-1--数据只读
#include <iostream>
#include <thread>
#include <vector>
// 共享只读数据
const std::vector<int> read_data = {1, 2, 3};
// 线程入口函数
void myprint(int i){
// 只读数据
std::cout << "thread " << i << " read data: " << read_data[0] << ","
<< read_data[1] << "," << read_data[2] << std::endl;
}
int main(int argc, char *argv[]){
std::vector<std::thread> V;
// 创建5个线程
for(int i = 0; i < 5; i++){
V.push_back(std::thread(myprint, i));
}
// 等待5个线程
for(auto iter = V.begin(); iter != V.end(); iter++){
iter->join();
}
// 继续执行主线程
std::cout << "This is main thread." << std::endl;
return 0;
}
2-2--数据读写
不同线程对共享数据进行读写时,可能会发生冲突,因此需要进行特殊的处理(例如加锁,线程间需互斥等);
2-3--共享数据保护简单案例
当两个线程对共享数据进行读写时,会发生冲突,可以通过互斥量(mutex)来对共享数据进行加锁(lock)、解锁(unlock)等操作;
lock() 与 unlock() 必须成对匹配,即调用次数相同;
必须使用同一个互斥量进行加锁和解锁;文章来源:https://www.toymoban.com/news/detail-650408.html
需要选择正确的临界区进行上锁和解锁,即保护区域需正确;文章来源地址https://www.toymoban.com/news/detail-650408.html
#include <iostream>
#include <thread>
#include <list>
#include <mutex> // 引入互斥
class myClass{
public:
// 收集数据到消息队列
void inMsgRecvQueue(){
for(int i = 0; i < 100; i++){
// 模拟收集消息
std::cout << "Running inMsgRecvQueue(), insert one value: "
<< i << std::endl;
// 选择正确的临界区进行加锁和解锁
my_mutex.lock();
msgRecvqueue.push_back(i); // 消息队列存储消息
my_mutex.unlock();
}
}
// 从消息队列取数据
void outMsgRecvQueue(){
for(int i = 0; i < 100; i++){
if(!msgRecvqueue.empty()){
// 选择正确的临界区并使用同一个互斥量进行加锁和解锁
my_mutex.lock(); // 加锁
// 取出数据
int command = msgRecvqueue.front();
msgRecvqueue.pop_front();
my_mutex.unlock(); // 解锁
}
else{
std::cout << "Running outMsgRecvQueue(), "
"the msgRecvqueue is empty" << std::endl;
}
}
}
private:
std::list<int> msgRecvqueue; // 消息队列
std::mutex my_mutex; // 创建互斥量
};
int main(int argc, char *argv[]){
myClass sample1;
// 使用成员函数创建线程
std::thread myInMsgObj(&myClass::inMsgRecvQueue, &sample1); // 收集数据线程
std::thread myOutMsgObj(&myClass::outMsgRecvQueue, &sample1); // 取出数据线程
myInMsgObj.join();
myOutMsgObj.join();
return 0;
}
到了这里,关于C++并发多线程--多个线程的数据共享和保护的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!