一、创建多个子线程

前面三章讲的例子都是只有一个子线程和主线程,然而实际中有多个子线程。那么下面介绍如何创建多个子线程。

 #include <iostream>
#include <vector>
#include <list>
#include <thread>
using namespace std; void mythread(int i)
{
cout << "id为" << std::this_thread::get_id() << "的线程" << endl;
cout << "i=" << i << endl;
return;
} int main()
{
vector<thread> mythreads;
for (int i = ; i < ; i++)
{
mythreads.push_back(thread(mythread, i)); //创建是10个线程并放入容器中
}
for (auto ite = mythreads.begin(); ite != mythreads.end(); ++ite)
{
ite->join(); //主线程等待10个线程执行完
}
cout << "主线程执行完毕" << endl;
system("pause");
return ;
}

运行结果

可以看出,虽然所有子线程执行完了才到主线程,但各个子线程的执行期间是乱的,没有谁等谁。那么就会引发一个数据共享的问题。

二、数据共享问题

如果多个线程之间知识单纯的读取数据,那么程序是不会出现奔溃等严重问题的,是安全稳定的。但如果既读数据又写数据,程序很有可能崩溃。比如有5个线程,2个线程写数据,3个线程读取同样的数据,试想如果写数据的线程还没写入数据,其他线程就进行读数据操作了,那么必然会出现问题。下面举一个例子说明。

 #include <iostream>
#include <vector>
#include <list>
#include <thread>
using namespace std;
//队列,先进先出
class A
{
private:
list<int> msg;
public:
//把数据写入队列
void inMsgRecv()
{
for (int i = ; i < ; i++)
{
cout << "插入一个元素" << i << endl;
msg.push_back(i);
}
}
//从队列读数据
void outMsgRecv()
{
for (int i = ; i < ; i++)
{
if (!msg.empty())
{
int GetMsg = msg.front(); //接受消息队列的首部
msg.pop_front(); //移除首部
//....然后可以对GetMsg进行你想要的操作
//cout << "GetMsg:" << GetMsg << endl;
}
else
{
cout << "没有数据可读" << endl;
}
}
}
}; int main()
{
A myobj;
//以成员函数作为线程函数,第一个&是取地址,第二个&是引用
thread mythread1(&A::inMsgRecv, &myobj);
thread mythread2(&A::outMsgRecv, &myobj);
mythread1.join();
mythread2.join();
system("pause");
return ;
}

运行结果

那么要处理多线程的数据共享问题,就要涉及一个概念“互斥量”,下面一章将会讲到。

C++多线程基础学习笔记(四)的更多相关文章

  1. Java基础学习笔记四 Java基础语法

    数组 数组的需求 现在需要统计某公司员工的工资情况,例如计算平均工资.最高工资等.假设该公司有50名员工,用前面所学的知识完成,那么程序首先需要声明50个变量来分别记住每位员工的工资,这样做会显得很麻 ...

  2. Java基础学习笔记(四) - 认识final关键字、权限修饰符和内部类

    一.final关键字 为什么要使用 final 关键字? 通过继承我们知道,子类可以重写父类的成员变量和方法.final 关键字可以用于修饰父类,父类成员变量和方法,使其内容不可以被更改. 1.被修饰 ...

  3. C++多线程基础学习笔记(一)

    下面分三个方面多线程技术的必须掌握一些基本知识. 1.进程 2.线程 3.并发 (1)进程 一个可执行程序运行起来了,即为创建了一个进程.如在电脑上打开了word,就创建了一个word进程,打开QQ, ...

  4. loadrunner基础学习笔记四

    在loadrunner中,通过将一系列操作标记为事务,可以将它们指定为要评测的操作. loadrunner收集关于事务执行时间长度的信息,并将结果显示在用不同单色标识的图和报告中. 可以这些信息了解应 ...

  5. JSP实现数据保存(web基础学习笔记四)

    session对象: //服务端设置Session属性 session.setAttribute("user", username); //客户端接收Session Object ...

  6. C++多线程基础学习笔记(十)

    一.Windows临界区的基本用法 CRITICAL_SECTION my_winsc;              //定义一个Windows的临界区,相当于一个mutex变量 InitializeC ...

  7. C++多线程基础学习笔记(九)

    一.std::atomic续谈 上一章说到std::atomic是针对一个变量的,这里补充一下针对的变量操作一般是++,+=,--,&=等等运算 .以下这种不可取:a=a+1; 二.std:: ...

  8. C++多线程基础学习笔记(八)

    shared_futrue和futrue_status的用法 shared_futrue是一个类模板,类似于futrue,不同的是它的成员函数get()可以使用多次,因为是复制数据,而futrue的g ...

  9. C++多线程基础学习笔记(七)

    一.std::async和std::future的用法 std::async是一个函数模板,std::future是一个类模板 #include <iostream> #include & ...

随机推荐

  1. HGOI 20190830 题解

    Problem A 钥匙 有$n$个人和$m$个钥匙在数轴上,人的坐标为$a_i$,钥匙的坐标为$b_i$ 而门的坐标为$p$,要让所有人获得一把不同钥匙,并且到达门,最长时间最短是多少. 对于$10 ...

  2. 灰度图像--图像增强 非锐化掩蔽 (Unsharpening Mask)

    学习DIP第35天 转载请标明本文出处:http://blog.csdn.net/tonyshengtan,欢迎大家转载,发现博客被某些论坛转载后,图像无法正常显示,无法正常表达本人观点,对此表示很不 ...

  3. Java实验课:命令行参数是什么?

    命令行参数:在命令行中给定的参数就是命令行参数.(即从输入位置角度理解). 命令行的参数 1. 什么是命令行的参数? 如: java Test1 365 156 "China" ( ...

  4. spark on yarn 动态资源分配报错的解决:org.apache.hadoop.yarn.exceptions.InvalidAuxServiceException: The auxService:spark_shuffle does not exist

    组件:cdh5.14.0 spark是自己编译的spark2.1.0-cdh5.14.0 第一步:确认spark-defaults.conf中添加了如下配置: spark.shuffle.servic ...

  5. Git客户端执行命令报错: fatal: Authentication failed for'xxxxx.git',但是又不弹出窗口重新输入用户名和密码的解决办法

    1.Git版本:Git-2.17.0 2.引起git报错的原因 在变更远程仓库路径的的时候,弹出过一个窗口输入用户名和密码,但是输错了,之后执行任何拉取和更新的命令都会报如下的错: fatal: Au ...

  6. MemoScope.Net

    What is MemoScope.Net ? It's a tool to analyze .Net process memory: it can dump an application's mem ...

  7. find 命令详细解释

    命令格式:find pathname -options [-print -exec -ok ...] 命令参数: pathname: find命令所查找的目录路径.例如用.来表示当前目录,用/来表示系 ...

  8. where in 的参数化查询实现

    身为一名小小的程序猿,在日常开发中不可以避免的要和where in和like打交道,在大多数情况下我们传的参数不多简单做下单引号.敏感字符转义之后就直接拼进了SQL,执行查询,搞定.若有一天你不可避免 ...

  9. 【makefile】make程序的命令行选项和参数

    Make命令参数的典型序列如下所示: make [-f makefile文件名][选项][宏定义][目标] 这里用[]括起来的表示是可选的.命令行选项由破折号“–”指明,后面跟选项,如: make – ...

  10. Struts2常量_Action配置路径_通配符

    Struts2中常用的常量 指定默认编码集,作用于HttpServletRequest的setCharacterEncoding方法 和freemarker .velocity的输出 <cons ...