C++11并发编程(一)——初始C++11多线程库

2023-11-12

1 前言
  C++11标准在标准库中为多线程提供了组件,这意味着使用C++编写与平台无关的多线程程序成为可能,而C++程序的可移植性也得到了有力的保证。
  在之前我们主要使用的多线程库要么是属于某个单独平台的,例如:POSIX线程库(Linux),Windows线程库(Windows),还有第三方数据库:Boost线程库。但是且不说性能上的不同,它们都有各自缺点,要么受平台限制无法系统间移植程序,要么需要下载第三方程序包来支持。相比较而言,我们当然更希望使用可移植的官方标准多线程库,这些在C++11中提供了组件,下面我们就一同来学习学习C++11中多线程库吧。
2 并发与并行的区别
  并发指的是两个或多个独立的活动在同一时段内发生。生活中并发的例子并不少,例如在跑步的时候你可能同时在听音乐;在看电脑显示器的同时你的手指在敲击键盘。这时我们称我们大脑并发地处理这些事件,只不过我们大脑的处理是有次重点的:有时候你会更关注你呼吸的频率,而有时候你更多地被美妙的音乐旋律所吸引。这时我们可以说大脑是一种并发设计的结构。这种次重点在计算机程序设计中,体现为某一个时刻只能处理一个操作。
  与并发相近的另一个概念是并行。它们两者存在很大的差别。并行就是同时执行,计算机在同一时刻,在某个时间点上处理两个或以上的操作。判断一个程序是否并行执行,只需要看某个时刻上是否多两个或以上的工作单位在运行。一个程序如果是单线程的,那么它无法并行地运行。利用多线程与多进程可以使得计算机并行地处理程序(当然 ,前提是该计算机有多个处理核心)。
  并发:同一时间段内可以交替处理多个操作:

这里写图片描述

  并行:同一时间段内同时处理多个操作:
这里写图片描述

  第一张图中两个任务队列同时等待一个处理器处理,两个队列可能约定交替着进行被处理,也可能是大家同时竞争被处理(通信)。后一种方式可能引起冲突:因为一个处理器无法同时进行两步操作。但在逻辑上看来,这个处理器是同时处理这两个队列。
  而第二张图中两个任务队列是并行处理,每个队列都有自己的独立处理器(或者核),两个队列中间没有竞争关系,队列中的某个排队者只需等待队列前面的消息处理完成,然后再轮到自己被处理。在物理上,如果是两个核的CPU宏观上看是同时处理这两个任务队列。
  并发的程序设计,提供了一种方式让我们能够设计出一种方案将问题(非必须地)并行地解决。如果我们将程序的结构设计为可以并发执行的,那么在支持并行的机器上,我们可以将程序并行地执行。因此,并发重点指的是程序的设计结构,而并行指的是程序运行的状态。并发编程,是一种将一个程序分解成小片段独立执行的程序设计方法。
3 并发的两种模式
  这里两种模式指的就是我们都知道的多线程并发与多进程并发的两种方法。
 3.1 多进程并发
  多个进程独立地运行,它们之间通过进程间常规的通信渠道传递讯息(信号,套接字,文件,管道等),这种进程间通信不是设置复杂就是速度慢,这是因为为了避免一个进程去修改另一个进程,操作系统在进程间提供了一定的保护措施,当然,这也使得编写安全的并发代码更容易。运行多个进程也需要固定的开销:进程的启动时间,进程管理的资源消耗。
 3.2 多线程并发
  在当个进程中运行多个线程也可以并发。线程就像轻量级的进程,每个线程相互独立运行,但它们共享地址空间,所有线程访问到的大部分数据如指针、对象引用或其他数据可以在线程之间进行传递,它们都可以访问全局变量。进程之间通常共享内存,但这种共享通常难以建立且难以管理,缺少线程间数据的保护。因此,在多线程编程中,我们必须确保每个线程锁访问到的数据是一致的。
4 C++中的并发与多线程
  C++标准并没有提供对多进程并发的原生支持,所以C++的多进程并发要靠其他API——这需要依赖相关平台。
  C++11 标准提供了一个新的线程库,内容包括了管理线程、保护共享数据、线程间的同步操作、低级原子操作等各种类。标准极大地提高了程序的可移植性,以前的多线程依赖于具体的平台,而现在有了统一的接口进行实现。
  C++11 新标准中引入了几个头文件来支持多线程编程:

  • < thread > :包含std::thread类以及std::this_thread命名空间。管理线程的函数和类在该头文件中有声明;
  • < atomic > :包含std::atomic和std::atomic_flag类,以及一套C风格的原子类型和与C兼容的原子操作的函数;
  • < mutex > :包含了与互斥量相关的类以及其他类型和函数;
  • < future > :包含两个Provider类(std::promise和std::package_task)和两个Future类(std::future和std::shared_future)以及相关的类型和函数;
  • < condition_variable > :包含与条件变量相关的类,包括std::condition_variable和std::condition_variable_any。
    4.1 实例来说
      我们先从一个最简单的也是最常见的单线程程序来看:
include<iostream>
using namespace std;

int main()
{
    cout<<"This is a test!"<<endl;
    return 0;
}

  上面程序就是一个单线程过程,main函数中打印一句话没有多余操作。那我们想另启一个线程来完成这个活怎么做呢?我们看下面的程序:

# include<iostream>
# include<thread>
using namespace std;

void subThread()
{
    cout<<"This is a test!"<<endl;
}

int main()
{
    thread t(subThread); // 创建另外一个线程
    t.join();            // 等待另一个线程执行完毕
}

  在上面程序中我们创建了另一个线程来完成打印工作。每个线程都必须有一个初始函数,新线程的执行开始于初始函数。对于第一段程序来说,它的初始函数是main,对于我们新创建的线程,可以在std::thread()对象的构造函数中指定。
  在第二段程序里,程序由两个线程组成:初始线程始于main,新线程始于subThread。这里将新线程t的初始函数指定为subThread。
  新线程启动之后会与初始进程一并运行,初始线程可以等待或不等待新进程的运行结束——如果需要等待线程,则新线程实例需要使用join(),否则可以使用detach()。如果不等待新线程,则初始线程自顾自地运行到main()结束。
  到此我们就创建了第一个基于C++11多线程库的多线程程序,一般来说并不值得为了如此简单的任务而使用多线程,尤其是在这期间初始线程并没做什么。后面我们会接触更深而更有意义的程序。


  参考文献:
  http://www.cnblogs.com/lpxblog/p/5190438.html
  http://blog.csdn.net/wrx1721267632/article/details/52197849

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++11并发编程(一)——初始C++11多线程库 的相关文章

随机推荐

  • Qt relaease添加调试

    Qt relaease添加调试 设置Qt安装路径下mkspecs common msvc desktop conf里的内容 QMAKE CFLAGS RELEASE WITH DEBUGINFO QMAKE CFLAGS OPTIMIZE
  • AndroidManifest中activity属性参数设置大全

    activity属性设置大全 android alwaysRetainTaskState true false android clearTaskOnLaunch true false android configChanges mcc m
  • 多节锂电串联保护板ic_如何有效保护锂电池板,一款优质的MOS管就能解决

    锂电池几乎应用于我们日常接触到的各类电器之中 但如何保护锂电池 你又是否知道呢 其实在锂电池保护板 最主要的元器件是IC与MOS MOS对锂电池板的保护作用非常大 它可以检测过充电 检测过放电 检测充电时过电电流 检测放电时过电电流 检测短
  • 在vue项目中使用SockJS实现websocket通信

    1 引入SockJS 和Stomp npm install sockjs client npm install stompjs import SockJS from sockjs client import Stomp from stomp
  • python里面读取h5文件报错OSError: Can‘t read data (address of object past end of allocation)

    报错如下 File h5py objects pyx line 54 in h5py objects with phil wrapper File h5py objects pyx line 55 in h5py objects with
  • C#通过WEBREQUEST调用WEBSERVICE

    1 首先通过WSDL说明创建SOAP消息 XML 2 创建WEBREQUEST 将XML加入WEBREQUEST的RequestStream 3 通过WEBREQUEST的Write函数发起请求 4 通过WEBREQUEST的GetResp
  • C语言中的小数

    一个数字 是有默认类型的 对于整数 默认是 int 类型 对于小数 默认是 double 类型 小数分为两种类型 float 4字节 double 8字节 表现形式 十进制形式 4 023 75 0 0 27 指数形式 7 25 102 0
  • Python爬取个性签名

    coding utf 8 import tkinter from tkinter import from tkinter import messagebox import requests import re from PIL import
  • spyder的cell如何使用(未写)

    目前不知道如何使用 看不出不同的cell分界线在哪
  • 常用知识点总结-自用

    文章目录 1 nohup 2 tmux 3 计算程序运行时间 4 计算模型大小 1 nohup nohup python u 文件名 gt log log 2 tmux 启动会话 tmux new s name 从会话跳出 ctrl b d
  • Mysql安装

    压缩包安装参考 https baijiahao baidu com s id 1632332658294840653 wfr spider for pc 配置环境变量 把mysql的bin目录配置到path变量 新增my ini文件初始化配
  • 如何安装openmpi

    安装openmpi 官网下载tar gz文件 解压缩 tar zxvf cd 到文件目录下 configure prefix usr local openmpi 安装目录 make j4 sudo make install 4核编译 添加环
  • Java反射获取SuperClass中的字段

    包 org springframework util ReflectionUtils ReflectionUtils findField clazz fieldName public class ReflectionTest public
  • DX滑块验证码别乱捅!一不小心就反爬了。

    大家好 我是TheWeiJun 欢迎来到我的公众号 今天我们将探讨一个有趣的话题 逆向滑块验证码 在互联网时代 随着网络安全问题日益引起人们的关注 各种验证码技术被广泛应用于各种网站和应用程序中 其中包括了滑块验证码 尽管滑块验证码是一种流
  • 最新论文阅读(20)

    TensorQuant A Simulation Toolbox for Deep Neural Network Quantization 2017年10月 TensorQuant toolbox Fraunhofer ITWM 一个研究所
  • 数据库多表链接查询的方式

    数据库中多表联查可以通过连接运算实现 即将多张表通过主外键关系关联在一起进行查询 分为非等值查询和等值查询两大类 非等值查询语法 select from 表1 表2 此查询方式的实质是笛卡尔积的应用 即表1有x行 表2有y行 得到的结果就是
  • DOM2详解

    目录 一 Document类型 1 属性 1 1 document documentElement 1 2 document body 1 3 document title 1 4 document URL 1 5 document dom
  • arcgis中将地理坐标转换为投影坐标 / 经纬度坐标转换

    arcgis中将地理坐标转换为投影坐标 经纬度坐标转换 1 导入需要转换的数据 以csv格式的点为例 1 File gt Add Data gt Add XY Data 2 选择导入的数据后将经纬度坐标分别赋予 X Field 和 Y Fi
  • 基于PCL的PCA算法实现点云的粗配准

    基于PCL的PCA算法实现点云的粗配准 一 引言 点云粗配准是三维重建和机器视觉中常见的任务之一 在点云数据中 我们需要找到两个或多个点云之间的刚性变换 以使它们对齐 主成分分析 PCA 是一种常用的数据降维和特征提取技术 也可以应用于点云
  • C++11并发编程(一)——初始C++11多线程库

    1 前言 C 11标准在标准库中为多线程提供了组件 这意味着使用C 编写与平台无关的多线程程序成为可能 而C 程序的可移植性也得到了有力的保证 在之前我们主要使用的多线程库要么是属于某个单独平台的 例如 POSIX线程库 Linux Win