计算机系统中的并发
多处理器:有多个处理器插座。
多核:一个处理器插座,只能有一个处理器安装,一个处理器有多个核心(独立执行计算的单元),每个核心可以有多个硬件线程(hart)
何为并发?
并发:单个系统在同时执行多个独立的任务。
- 硬件并发:一台计算机系统提供多个核心、单个CPU提供多个硬件线程(hart)。
- 软件并发:单个核心执行任务切换(task switch)。
如果只有纯硬件并发,那么计算有多少硬件线程,就只能执行多少任务。
而软件并发,理论上可以在迷惑应用程序和用户的前提下,“同时”执行多个任务。
因此,现代计算机系统的并发是二者的结合。
硬件并发和软件并发还是有着许多不同:
- 内存模型的假设
- 任务切换的负担
并发的方式(手段)
- 多进程(每个进程只有一个执行线程)
- 多线程(每个进程有多个执行线程)
多进程并发
每个进程独立获得资源,进程之间互不干扰。
通过进程间通信手段进行通信
- 信号
- 共享内存
- 管道
- 信号量
- 消息队列
- 等
缺点:
- 进程切换开销大,导致速度慢
- 进程管理需要操作系统维持(通过维持某些数据结构)
优点:
- 各个任务之间独立,安全性高。
多线程并发
在单个进程中执行多个线程。
- 线程之间共享同一进程的大部分资源
- 但可以有自己的执行序列(PC寄存器),因此,可以同时独立完成多个任务。
缺点:
- 同一个进程的共享数据的访问,要被正确同步。
多个单线程/进程间的通信(包含启动)要比单一进程中的多线程间的通信(包括启动)的开销大,若不考虑共享内存可能会带来的问题,多线程将会成为主流语言(包括C++)更青睐的并发途径。此外,C++标准并未对进程间通信提供任何原生支持,所以使用多进程的方式实现,这会依赖与平台相关的API。因此,本书只关注使用多线程的并发,并且在此之后所提到“并发”,均假设为多线程来实现。
并发与并行
不同的关注点
并行关注点:更注重性能,如何利用当前硬件的所有资源,来提高任务处理速度。
并发关注点:任务分离,任务响应。
关注点分离
互相独立的功能模块,可以在同一应用(进程)中分离,并行执行完成的任务,再进行信息的交换(需要手动处理交互逻辑)。
这种思想使得,线程的数量不再依赖CPU中可用(hart)的数量,因为对线程的划分是基于概念上的设计,而不是一种增加吞吐量的尝试(根本目的并不是为了能够处理更多任务,但这样做确实大部分情况下都能增加吞吐量。)。
并发的方式
- 指令级并行
- 数据级并行
- 线程级并性(任务并行)
- 多机并行