
C++并发与多线程(三)
发布日期:2021-05-07 15:56:01
浏览次数:12
分类:技术文章
本文共 3454 字,大约阅读时间需要 11 分钟。
创建多个线程、数据共享问题、案例代码
1.创建个等待多个线程
// 并发与多线程2_4.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。//#include "pch.h"#include#include #include using namespace std;void Myprint(int inum){ cout << "myprint线程开始执行了,线程编号" << inum << endl; cout << "myprint线程结束执行了,线程编号" << inum << endl;}int main(){ //一 创建线程和等待多个线程 vector mythreads; //创建10个线程,线程入口函数统一使用 myprint //1)多线程执行顺序是乱的 //2)这种join写法更容易写出稳定程序 //3)把thread对象放入到容器里,对管理大量线程有帮助 for (int i = 0; i < 10; i++) { //创建10个线程,已经开始执行 mythreads.push_back(thread(Myprint, i)); } for (auto iter = mythreads.begin(); iter != mythreads.end(); ++iter) { iter->join(); } cout << "I LOVE CHINA" << endl;}
2.数据共享问题分析
2.1只读数据共享
只读数据共享安全稳定
// 并发与多线程2_4.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。//#include "pch.h"#include#include #include using namespace std;vector g_v = { 1,2,3 };void Myprint(int inum){ cout << "myprint线程开始执行了,线程编号" << inum << endl; cout << "myprint线程结束执行了,线程编号" << inum << endl; cout << "id 为" << std::this_thread::get_id() << "打印g_v值" << g_v[0] << g_v[1] << g_v[2] << endl;}int main(){ //一 创建线程和等待多个线程 vector mythreads; //创建10个线程,线程入口函数统一使用 myprint //1)多线程执行顺序是乱的 //2)这种join写法更容易写出稳定程序 //3)把thread对象放入到容器里,对管理大量线程有帮助 for (int i = 0; i < 10; i++) { //创建10个线程,已经开始执行 mythreads.push_back(thread(Myprint, i)); } for (auto iter = mythreads.begin(); iter != mythreads.end(); ++iter) { iter->join(); } cout << "I LOVE CHINA" << endl; //二 数据共享 //2.1只读数据}
2.2 有读有写的数据
最简单的不崩溃处理 读和写不能同时进行
3.共享数据的保护案例代码
如果写和读同时进行,则会报错
这里就需要一个保护共享数据的互斥量的概念// 并发与多线程2_4.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。//#include "pch.h"#include#include #include #include using namespace std;//vector g_v = { 1,2,3 };////void Myprint(int inum)//{ // cout << "myprint线程开始执行了,线程编号" << inum << endl;// cout << "myprint线程结束执行了,线程编号" << inum << endl;// cout << "id 为" << std::this_thread::get_id() << "打印g_v值" << g_v[0] << g_v[1] << g_v[2] << endl;////}class A{ public: //把玩家命令放入到一个队列的进程 void inMsgRecvQueue() { for (int i = 0; i < 100; i++) { cout << "inMsgRecvQueue执行,插入一个元素" << i << endl; msgRecvQueue.push_back(i); //假设数字i为命令 放入队列 } } //读取命令的线程 void outMsgRecvQueue() { for (int i = 0; i < 100; i++) { if (!msgRecvQueue.empty()) { int command = msgRecvQueue.front(); //返回第一个元素但不检查元素是否存在 msgRecvQueue.pop_front(); //移除第一个元素但不返回 //处理数据。。。。。 } else { cout << "outMsgRecvQueue()执行,但目前消息队列为空" < << endl; } } cout << "end" << endl; }private: std::list msgRecvQueue;};int main(){ // //一 创建线程和等待多个线程 //vector
mythreads; 创建10个线程,线程入口函数统一使用 myprint 1)多线程执行顺序是乱的 2)这种join写法更容易写出稳定程序 3)把thread对象放入到容器里,对管理大量线程有帮助 //for (int i = 0; i < 10; i++) //{ // //创建10个线程,已经开始执行 // mythreads.push_back(thread(Myprint, i)); // //} //for (auto iter = mythreads.begin(); iter != mythreads.end(); ++iter) //{ // iter->join(); //} //cout << "I LOVE CHINA" << endl; //二 数据共享 //2.1只读数据 //2.2 有读有写 //最简单的不崩溃处理 读和写不能同时进行 //2.3其他案例 //数据共享: //三 共享数据的保护案例代码 //网络游戏服务器,有两个自己创建的线程,一个线程手机玩家命令(数字表示),并把名利数据写入到一个队列中。 //另一个线程从队列中取出玩家发送来的命令,解析,然后执行玩家的动作。 //使用list,频繁的按顺序插入和删除时效率较高 //用成员函数作为线程函数的方法写线程 A myobja; thread myOutnMsg(&A::outMsgRecvQueue, &myobja); thread myInMsgObj(&A::inMsgRecvQueue, &myobja); myOutnMsg.join(); myInMsgObj.join();}
发表评论
最新留言
不错!
[***.144.177.141]2025年03月17日 19时48分53秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
【MySQL】(四)SQL 基础操作之 DQL 数据查询语言
2019-03-05
【MySQL】(八)视图
2019-03-05
【MySQL】(九)触发器
2019-03-05
关于Altium Designer 09导出BOM表不能正确分类问题
2019-03-05
Oracle 11G环境配置
2019-03-05
【Spark】(六)Spark 运行流程
2019-03-05
你还不会在CentOS7上安装Docker嘛?
2019-03-05
Docker命令锦集
2019-03-05
【Python】(十二)IO 文件处理
2019-03-05
【Hive】(二十)详解 Hive 四种排序的区别
2019-03-05
【Hive】函数 instr 的用法
2019-03-05
SSM框架整合详解
2019-03-05
【Oozie】(三)Oozie 使用实战教学,带你快速上手!
2019-03-05
师兄面试遇到这条 SQL 数据分析题,差点含泪而归!
2019-03-05
Java面试题——基础篇
2019-03-05
Java8新特性——并行流与顺序流
2019-03-05
4位右移寄存器模型(D触发器)
2019-03-05
同步1110序列检测电路
2019-03-05
阿里云大数据ACP(四)机器学习 PAI
2019-03-05
如何通过 Dataphin 构建数据中台新增100万用户?
2019-03-05