C++并发编程实践笔记(一)—— 初识并发

1.何为并发

并发是指两个或者多个独立的活动同时发生。

1.1并发的类型

  • 单核系统的并发
    对于比较古老的机器,只有单个处理单元或者单个核心。计算机在某一时刻只可以真正执行一个任务,但它可以通过在极短时间内在多个任务之间进行切换,看起来就像多个任务在同时执行。

  • 多核系统的并发
    包含多个处理器的计算机用于服务器和高性能的计算任务已经有很多年了,现在急于单个芯片上具有多余一个核心的处理器也越来越常见。无论它们拥有多个处理器或者是一个多核的处理器,这些计算机都能够真正的并行运行超过一个任务,我们称这种情况为硬件并发。

1.2并发的途径

1.2.1多进程并发

在一个应用程序中使用并发的第一种方法是将应用程序分为多个、独立的、单线程进程。这些独立的进程可以通过常规的进程间通信渠道(信号、套接字、文件和管道等)互相传递信息。
这里写图片描述
多进程并发的优点

  • 操作系统在进程间提供了附加的保护操作和更高级的通信机制,意味着可以比线程更容易写安全的并发代码。
  • 可以通过网络连接不同机器上运行的独立进程

多进程并发的缺点

  • 进程间通信往往很复杂或者速度较慢
  • 多进程相对于多线程需要更多的资源开销

1.2.2多线程并发

并发的另一个途径是在单个进程中运行多个线程。线程很像轻量级的进程,每个线程独立运行,且每个线程可以运行不同的指令序列。
这里写图片描述
多线程并发的优点

  • 线程之间交换数据非常方便
  • 由于所有线程共享存储,开销较小

多线程并发的缺点

  • 一个线程崩溃将导致整个进程崩溃
  • 线程之间同步比较麻烦

2.为什么使用并发

关注点分离
通过将相关的代码放在一起并将无关的代码分开,可以使你的代码更加容易理解和测试。

性能
如果软件想利用日益增长的计算能力,它必须被设计为并发运行多个任务。
将一个任务分为几个部分各自并行运行,从而降低总的运行时间。

限制并发量
并发是有成本的,一方面是更加复杂的编程和维护过程,另一方面是更加大的开销。
系统资源是有限的,能够支持的并发数量也是有限的。如果让超过合适数量的进程或线程同时运行,则会导致系统运行缓慢,最终效果可能不及运行更少数量的线程。运行越多的线程,操作系统就需要做越多的上下文切换,每次上下文切换都需要耗费时间,如果用于切换上下文的时间相比处理有效任务的时间占比太大就不划算了。

3.C++线程库

从C++11标准库开始支持标准线程,标准线程具有跨平台的特性,可以更加方便的写出可移植的代码。
C++中对原子操作的直接支持,允许程序员写出具有确定语义、可移植的高效代码。

扫描二维码关注公众号,回复: 5773304 查看本文章

对参与高性能计算的开发者常常关注的一点就是效率。如果你追求极致的性能,那么理解与直接使用底层的低级工具相比,使用高级工具所带来的实现成本是很重要的。这个成本就是抽象的惩罚(abstraction penalty)。
C++标准委员会在设计线程库时就考虑到这一点了,其设计的目标就是通过直接使用低级的API几乎或者完全无法得到更高的性能,因此,该线程库被设计为在大部分平台都能高效的实现。

C++标准委员会的另一个目标是确保那些与硬件打交道的C++程序员获取终极性能。为了达到这个目的,伴随着新的内存模型,出现了一个全面的原子操作库,用于直接控制单个位、字节、线程间同步以及所有变化的可见性。这些原子类型和相应的操作可以 在很多地方加以使用,而这些地方以前通常被开发者选择下放到平台相关的汇编语言中。使用新的标准类型和操作具有更加好的可移植性,并且更加易于维护。

4.并发编程的hello world

#include <iostream>
#incldue <thread>

void Hello() {
    std::cout << "Hello world" << std::endl;
}

int main() {
    std::thread t(Hello);
    t.join();
}

这里调用 t.join() 的目的是为了防止新线程还没有运行主线程就结束的可能性。

猜你喜欢

转载自blog.csdn.net/zhuiyuanqingya/article/details/81517676