C++11并发与多线程笔记(4) 创建多个线程、数据共享问题分析、案例代码

C++11并发与多线程笔记(4) 创建多个线程、数据共享问题分析、案例代码

  • 1、创建和等待多个线程
  • 2、数据共享问题分析
    • 2.1 只读的数据
    • 2.2 有读有写
    • 2.3 其他特例
  • 3、共享数据的保护案例代码

1、创建和等待多个线程

#include<iostream>
#include<thread>
#include <vector>
using namespace std;
//线程入口函数
void myPrint(int inum) {cout << "myPrint线程开始执行了,线程编号= "<<inum << endl;// ....doWorkcout << "myPrint线程结束执行了,线程编号= "<<inum << endl;
}
int main() {//1、创建和等待多个线程vector<thread> mythreads;for (int i = 0; i < 10; i++) {mythreads.push_back(thread(myPrint, i));//创建10个线程,线程入口函数统一使用myPrint(匿名对象)}for (auto iter = mythreads.begin(); iter != mythreads.end(); ++iter) {iter->join();//等待10个线程都返回}cout << "I love China!" << endl;return 0;
}
  • 多个线程执行顺序是乱的,跟操作系统内部对线程的运行调度机制有关;
  • 主线程等待所有子线程运行结束,最后主线程结束
  • 把thread对象放入到容器里管理,看起来像个thread对象数组,这对一次创建大量的线程并对大量线程进行管理很方便

2、数据共享问题分析

2.1 只读的数据

//线程入口函数
vector<int> g_v = { 1,2,3 };//共享数据,只读,不写
void myPrint(int inum) {cout << "id 为 " << this_thread::get_id() << " 的线程 打印g_v的值: " << g_v[0] << g_v[1] << g_v[2] << endl;//只读return;
}
int main() {vector<thread> mythreads;for (int i = 0; i < 10; i++) {mythreads.push_back(thread(myPrint, i));}for (auto iter = mythreads.begin(); iter != mythreads.end(); ++iter) {iter->join();//等待10个线程都返回}cout << "I love China!" << endl;return 0;
}

在这里插入图片描述

只读的数据,是安全稳定的,不需要特别什么处理手段。直接读就可以;

2.2 有读有写

有读有写:假设有2个线程,8个线程,如果代码没有特别的处理,那程序肯定崩溃;

最简单的防止崩溃方法:读的时候不能写,写的时候不能读。2个线程不能同时写,8个线程不能同时读

写的动作分10小步,由于任务切换,导致各种诡异的事情发生(最可能的诡异的事情还是崩溃)

2.3 其他特例

  • 数据共享
  • 北京–深圳火车 T123,10个售票窗口卖票 1,2窗口 同时都要订99座

3、共享数据的保护案例代码

网络游戏服务器

  • 两个自己创建的线程,一个线程收集玩家命令(用一个数字代表玩家发来的命令),并把命令数据写到一个队列。
  • 另外一个线程从队列中取出玩家发送来的命令,解析,然后执行玩家需要的动作﹔

vector, list , list跟vector。list:频繁随机插入和删除数据时效率高。vector容器查找效率高,尾部插入效率高。

#include<iostream>
#include<thread>
#include <vector>
#include<list>
using namespace std;class A {
public://把收到的消息(玩家命令)加入到一个队列的线程void inMsgRecvQueue() {for (int i = 0; i < 100000; i++) {cout << "inMsgRecvQueue()执行,插入一个元素 " << i << endl;msgRecvQueue.push_back(i);// 假设这个数字i就是收到的命令,直接弄到消息队列里边来}}//把数据从消息队列中取出的线程void outMsgRecvQueue() {for (int i = 0; i < 100000; i++) {if (!msgRecvQueue.empty()) {//消息不为空int command = msgRecvQueue.front();//返回第一个元素,但不检查元素是否存在msgRecvQueue.pop_front();//移除第一个元素,但不返回//.... 这里就考虑处理数据}else {//消息队列为空cout << "outMsgRecvQueue()执行,但目前消息队列中为空" << i << endl;}cout << "end" << endl;}}
private:list<int> msgRecvQueue;//容器,专门用于存放玩家发来的命令
};int main() {A myobja;//线程通过对象的成员函数时,第二个参数需要是对象的地址,因为成员函数运行时需要用到this指针thread mythreadInMsgRecv(&A::inMsgRecvQueue, &myobja);thread mythreadOutMsgRecv(&A::outMsgRecvQueue, &myobja);mythreadInMsgRecv.join();mythreadOutMsgRecv.join();cout << "I love China!" << endl;return 0;
}

目前问题:程序不稳定,读写没控制,造成错误
解决方法:引入一个c++解决多线程保护共享数据问题的第一个概念“互斥量”

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/93964.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

世界上最著名的密码学夫妻的历史

Alice和Bob是密码学领域里最著名的虚拟夫妻&#xff0c;自1978年“诞生”以来&#xff0c;到走进二十一世纪的移动互联网时代&#xff0c;作为虚构的故事主角&#xff0c;Alice和Bob不仅在计算机理论、逻辑学、量子计算等与密码学相关的领域中得到应用&#xff0c;他们的名字也…

springboot+VUE智慧公寓管理系统java web酒店民宿房屋住宿报修信息jsp源代码

本项目为前几天收费帮学妹做的一个项目&#xff0c;Java EE JSP项目&#xff0c;在工作环境中基本使用不到&#xff0c;但是很多学校把这个当作编程入门的项目来做&#xff0c;故分享出本项目供初学者参考。 一、项目描述 springbootVUE智慧公寓管理系统 系统有2权限&#xf…

Java课题笔记~ SpringMVC拦截器

SpringMVC 中的 Interceptor 拦截器&#xff0c;它的主要作用是拦截指定的用户请求&#xff0c;并进行相应的预处理与后处理。其拦截的时间点在“处理器映射器根据用户提交的请求映射出了所要执行的处理器类&#xff0c;并且也找到了要执行该处理器类的处理器适配器&#xff0c…

游戏中的UI适配

引用参考&#xff1a;感谢GPT UI适配原理以及常用方案 游戏UI适配是确保游戏界面在不同设备上以不同的分辨率、屏幕比例和方向下正常显示的关键任务。下面是一些常见的游戏UI适配方案&#xff1a; 1.分辨率无关像素&#xff08;Resolution-Independent Pixels&#xff09;&a…

动设备状态监测:智能化生产的关键利器

动设备状态监测正引领着工业生产的智能化转型。本文将深入探讨动设备状态监测的意义、PreMaint在其中的角色&#xff0c;以及如何实现智能化生产&#xff0c;提高生产效率和可靠性。 1. 动设备状态监测的重要性 随着制造业的发展&#xff0c;设备的状态监测变得至关重要。动设…

JVM——类加载器

回顾一下类加载过程 类加载过程&#xff1a;加载->连接->初始化。连接过程又可分为三步:验证->准备->解析。 一个非数组类的加载阶段&#xff08;加载阶段获取类的二进制字节流的动作&#xff09;是可控性最强的阶段&#xff0c;这一步我们可以去完成还可以自定义…

Modbus_TCP协议如何使用?

1 驱动简介 网关支持标准的Modbus-TCP协议&#xff0c;支持Modbus-TCP协议的设备&#xff08;例如智能仪表、电表等&#xff09;&#xff0c;都可以通过此协议直接通讯&#xff0c;实现远程采集、监控、控制设备的功能。 从站号&#xff1a;默认为1&#xff0c;需要查看设备说…

机器学习算法之-逻辑回归(2)

为什么需要逻辑回归 拟合效果太好 特征与标签之间的线性关系极强的数据&#xff0c;比如金融领域中的 信用卡欺诈&#xff0c;评分卡制作&#xff0c;电商中的营销预测等等相关的数据&#xff0c;都是逻辑回归的强项。虽然现在有了梯度提升树GDBT&#xff0c;比逻辑回归效果更…

多线程-死锁

/*** 死锁demo*/ public class DeadlockDemo {public static void main(String[] args) {// 创建两个对象final Object resource1 "resource1";final Object resource2 "resource2";// 创建第一个线程Thread t1 new Thread(() -> {// 尝试锁定resour…

python模块中的_all__属性的作用

文章目录 前言 一、python模块中的_all__属性的作用 总结 前言 python模块中的特殊变量_all__的用法总结。 一、python模块中的_all__属性的作用 顾名思义&#xff1a;我们如果导一个包里面的函数或者变量&#xff0c;会把暴露在外部的变量和函数导出。那么有些变量或者函…

Vim在Mac电脑中的下载与安装方法:MacVim

本文介绍在Mac系统电脑中&#xff0c;下载、安装文本编辑器Vim软件&#xff08;MacVim软件&#xff09;的具体方法。 在Mac系统电脑中&#xff0c;原本就带有一个非图形界面的Vim&#xff1b;只要我们在终端中&#xff0c;输入如下的代码&#xff0c;就可以查看系统自带的非图形…

651页23万字智慧教育大数据信息化顶层设计及建设方案WORD

导读&#xff1a;原文《651页23万字智慧教育大数据信息化顶层设计及建设方案WORD》&#xff08;获取来源见文尾&#xff09;&#xff0c;本文精选其中精华及架构部分&#xff0c;逻辑清晰、内容完整&#xff0c;为快速形成售前方案提供参考。 目录 一、 方案背景 1.1 以教育…

windows下载安装FFmpeg

FFmpeg是一款强大的音视频处理软件&#xff0c;下面介绍如何在windows下下载安装FFmpeg 下载 进入官网: https://ffmpeg.org/download.html, 选择Windows, 然后选择"Windows builds from gyan.dev" 在弹出的界面中找到release builds, 然后选择一个版本&#xff0…

使用windows搭建WebDAV服务,并内网穿透公网访问【无公网IP】

文章目录 1. 安装IIS必要WebDav组件2. 客户端测试3. 使用cpolar内网穿透&#xff0c;将WebDav服务暴露在公网3.1 打开Web-UI管理界面3.2 创建隧道3.3 查看在线隧道列表3.4 浏览器访问测试 4. 安装Raidrive客户端4.1 连接WebDav服务器4.2 连接成功4.2 连接成功 1. Linux(centos8…

打印出二进制的奇数位和偶数位

void print(int a) {int i0;printf("奇数位&#xff1a;");for(i30;i>0;i-2){printf("%d ",(a>>i)&1);}printf("\n");printf("偶数位&#xff1a;");for(i31;i>1;i-2){printf("%d ",(a>>i)&1);} …

多维时序 | MATLAB实现PSO-CNN-BiGRU多变量时间序列预测

多维时序 | MATLAB实现PSO-CNN-BiGRU多变量时间序列预测 目录 多维时序 | MATLAB实现PSO-CNN-BiGRU多变量时间序列预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 1.多维时序 | MATLAB实现PSO-CNN-BiGRU多变量时间序列预测&#xff1b; 2.运行环境为Matlab20…

SpringBoot-Hello World

SpringBootWeb快速入门 创建Springboot工程&#xff0c;并勾选web开发相关依赖定义HelloController类&#xff0c;添加方法hello&#xff0c;并添加相关注释运行测试 创建新的SpringBoot项目 几个注意的点&#xff1a; Name&#xff1a;基本上不用管&#xff0c;会根据下面的Ar…

Datawhale Django后端开发入门 TASK03 QuerySet和Instance、APIVIew

一、QuerySet QuerySet 是 Django 中的一个查询集合&#xff0c;它是由 Model.objects 方法返回的&#xff0c;并且可以用于生成数据库中所有满足一定条件的对象的列表。 QuerySet 在 Django 中表示从数据库中获取的对象集合,它是一个可迭代的、类似列表的对象集合。主要特点…

复数

文章目录 复数虚数 i i i几何解释 复数复数的性质复数的加法1. 加实部2. 加虚部3. 组合实部和虚部复数加法的几何解释总结 复数减法1. 减实部2. 减虚部3. 组合实部和虚部复数减法的几何解释总结 复数乘法1. 展开乘法2. 使用 i 2 − 1 i^2 -1 i2−13. 合并实部和虚部复数乘法…

conda常用命令及国内镜像源

conda命令使用介绍 启动conda source ~/.bashrc帮助目录 conda create -h检查conda版本 conda --version升级当前版本的conda conda update conda环境管理 列出所有的环境 conda info -e conda env list安装一个不同版本的python新环境 conda create --name py27 pytho…