C++并发世界
1.什么是并发
- 并发是指两个或更多独立的活动同时发生。举个栗子:我们可以一边走路一边说话;
1.1、计算机系统中的并发
大多数计算机都有一个处理器,具有单个处理单元或核心,至今许多台式机器仍是这样。这种计算机在某一个时刻只可以真正执行一个任务,但它可以美妙切换任务很多次;
- 这样叫做任务切换,也称之为并发;
包含多个处理器的计算机用于服务器和高性能计算任务已经很多年,现在基于单个芯片上具有多于一个核心的处理器(多核处理器)的计算机越来越普遍;
- 无论它们拥有多个处理器或一个处理器,这些计算机能够真正的并行运行超过一个任务。我们才称之为硬件并发
在一个双核机器(具有两个处理核心)中,每个任务可以在各自的核心执行;
在单核机器上做任务切换时,每个任务的块交织进行;
- 为了实现交替进行,每一次人物切换都要执行一次上下文切换,并且需要时间;
尽管硬件并发的可用性在多处理器或多核系统上更显著,有些处理器却可以在一个核心上执行多个线程。
- 要考虑的因素是硬件线程
1.2 并发的途径
1.2.1 有多个单线程的进程
- 对应1.3
1.2.2 在一个进程中有多个线程
- 对应1.4
1.3 多进程并发
- 优点
- 比线程更容易的编写安全的并发代码;
- 可以通过网络连接的不同的机器上运行独立的进程;
- 缺点
- 进程之间的通信复杂,速度较慢;
- 运行多个进程所需的固有开销;
- 启动进程需要世界;
- 依赖平台相关的API来实现;
1.4 多线程并发
- 优点
- 启动单一进程的多线程之间通信的开销更小;
- C++在内的主流语言更青睐的开发途径;
- 缺点
- 进程之间共享内存难以建立并且难以管理;
- 缺少线程间的数据保护;
- 开发前需要对线程间通信作大量思考;
2.为什么使用并发
2.1 为了划分关注点
带来响应性的错觉,使用线程一般会使每个线程的逻辑更加简单,之间的交互可以被限制为清晰可辨的点。
线程的数量与CPU可用内核的数量无关,因为对线程的划分使基于概念上的设计而不是视图增加吞吐量。
2.2 为了性能而使用
Herb Sutter 说:如果软件想要利用日益增长的计算能力,它必须设计为并发运行多个任务。
有两种方式为了性能使用并发:
1、将一个单个任务分成几部分且各自并行运行,从而降低总运行时间,这就是任务并行。
2、每个线程在不同的数据部分上执行相同的操作,后一种方法被称之为数据并行。
2.3 什么时候不使用并发
收益比不上成本的时候。使用并发的代码在很多情况下难以理解,因此编写和维护多线程代码需要很多成本。
性能增益可能没有预期那么大。
线程是有限资源,让太多的线程同时运行,会消耗操作系统资源,使操作系统整体运行缓慢。每个线程都需要一个独立的对战空间。例如一个可用地址控件限制为4GB的扁平架构的32位进程来说,如果每个线程都有一个1MB的堆栈,那么496个线程就会用尽所有地址空间,不再位代码、静态数据或者堆数据留有空间。
越多的线程,操作系统需要做越多的上下文切换,增加一个线程,一定程度上会降低应用程序的整体性能。
3. C++中使用并发和多线程
在1998 C++ 标准中,你没办法在缺少编译器相关扩展的情况下编写多线程应用。
书中按照C++11标准的方式编写开发。
4. 开始入门
#include<iostream>
#include<thread> // <---1
void hello() { // <---2
std::cout<<"hello Concurrent World
";
}
int main() {
std::thread t(hello); // <---3
t.join(); // <---4
}
- 1、标准库C++中对多线程支持的声明文件包含;
- 2、独立函数
- 3、std:: thread对象的构造函数指定t;
- 4、t.join()调用线程运行;