c++并发编程

C++ 多线程与内存模型资料汇
参考阿里云文章
参考linux kernel perfbook
参考C++并发编程

  • 并发编程算法总体上分为两大类
    blocking algorithms
    non-blocking algorithms

  • blocking algorithms
    1)blocking
    一个方法被称为阻塞的,即这个方法在其演进过程中不能正常运行直到其他(占有锁的)线程释放。
    2)starvation-free(也称无闭锁)
    只有当底层平台/系统提供了明确的保障以后讨论这个性质才有意义。
    希望进入互斥区的线程最终都能进入。

  • non-blocking algorithms (参见non-blocking algorithm)
    1)Obstruction-Free(Maurice Herlihy,Mark Moir和Victor Luchangco所提出的Double-ended Queue)
    Obstruction-free 是指在任何时间点,一个孤立运行线程的每一个操作可以在有限步之内结束。只要没有竞争,线程就可以持续运行,一旦共享数据被修改,Obstruction-free 要求中止已经完成的部分操作,并进行回滚,obstruction-free 是并发级别更低的非阻塞并发,该算法在不出现冲突性操作的情况下提供单线程式的执行进度保证,所有 Lock-Free 的算法都是 Obstruction-free 的。
    2)Lock-Free
    Lock-freedom 指的是整个系统作为一个整体一直运行下去,系统内部单个线程某段时间内可能会饥饿,这是比wait-freedom弱的并发级别,但系统整体上看依然是没有阻塞的。所有wait-free的算法显然都满足lock-free的要求。
    3)Wait-Free
    Wait-freedom 指的是每一个线程都一直运行下去而无须等待外部条件,整个流程中任何操作都能在一个有限的步骤内完成,这是最高的并发级别,没有任何阻塞。

0.并发的相关知识点

0.1 并行与并发

  • 计算机中的并发,指的是在单一系统中,同时执行多个独立的活动。对于多核系统,它们在同一时刻进行的活动,则称为并行。
    希望进入互斥区域的线程最终都能够进入互斥区域(即使之前在互斥区中的线程意外停止了)。

0.2 多进程和多线程并发

  • 多进程并发
    多个进程独立地运行,它们之间通过进程间常规的通信渠道传递讯息(信号,套接字,文件,管道等),这种进程间通信不是设置复杂就是速度慢,这是因为为了避免一个进程去修改另一个进程,操作系统在进程间提供了一定的保护措施,当然,这也使得编写安全的并发代码更容易。
    运行多个进程也需要固定的开销:进程的启动时间,进程管理的资源消耗。

  • 多线程并发
    线程就像轻量级的进程,每个线程相互独立运行,但它们共享地址空间,所有线程访问到的大部分数据如指针、对象引用或其他数据可以在线程之间进行传递,它们都可以访问全局变量。进程之间通常共享内存,但这种共享通常难以建立且难以管理,缺少线程间数据的保护。因此,在多线程编程中,我们必须确保每个线程锁访问到的数据是一致的。

0.3 同步和异步

0.3.1 同步和异步概念

  • 同步
    就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回。也就是必须一件一件事做,等前一件做完了才能做下一件事。

  • 异步
    当一个异步过程调用发出后,调用者不能立刻得到结果。实际处理这个调用的部件在完成后,通过状态、通知和回调来通知调用者。
    如果执行部件用状态来通知,那么调用者就需要每隔一定时间检查一次,效率就很低。如果是使用通知的方式,效率则很高,因为执行部件几乎不需要做额外的操作。至于回调函数,其实和通知没太多区别。

0.3.2 同步传输和异步传输概念

  • 同步传输
    通常,同步传输是以数据块为传输单位。每个数据块的头部和尾部都要附加一个特殊的字符或比特序列,标记一个数据块的开始和结束,一般还要附加一个校验序列 (如16位或32位CRC校验码),以便对数据块进行差错控制。所谓同步传输是指数据块与数据块之间的时间间隔是固定的,必须严格地规定它们的时间关系。

  • 异步传输
    通常,异步传输是以字符为传输单位,每个字符都要附加 1 位起始位和 1 位停止位,以标记一个字符的开始和结束,并以此实现数据传输同步。所谓异步传输是指字符与字符(一个字符结束到下一个字符开始)之间的时间间隔是可变的,并不需要严格地限制它们的时间关系。
    异步传输又称为起止式异步通信方式,其优点是简单、可靠,适用于面向字符的、低速的异步通信场合。例如,计算机与Modem之间的通信就是采用这种方式。它的缺点是通信开销大,每传输一个字符都要额外附加2~3位,通信效率比较低。例如,在使用Modem上网时,普遍感觉速度很慢,除了传输速率低之外,与通信开销大、通信效率低也密切相关。

0.3.3 阻塞和非阻塞、同步和异步

  • 同步
    执行一个操作之后,等待结果,然后才继续执行后续的操作

  • 异步
    执行一个操作后,可以去执行其他的操作,然后等待通知再回来执行刚才没执行完的操作
    访问数据的方式,同步需要主动读写数据,在读写数据的过程中还是会阻塞;异步只需要I/O操作完成的通知,并不主动读写数据,由操作系统内核完成数据的读写。

  • 阻塞
    进程给CPU传达一个任务后,一直等待CPU处理完成,然后才执行后面的操作

  • 非阻塞
    进程给CPU传达任务后,继续处理后续操作,隔断时间再来询问之前的操作是否完成。
    进程/线程要访问的数据是否就绪,进程/线程是否需要等待。

1.多线程相关的头文件

1.1 thread support library

  • 这些库包括


    条件变量
  • “Thread support library”可以简单想象成POSIX线程库的OO版本,对常用的Threads、Mutex、Condition Variables、Futures等概念进行了很好的封装,其实它的前身就是Boost::Thread.

1.2 atomic operations library

  • “Atomic operations library”顾名思义,其实就是原子操作库。而在以往,我们往往需要借助汇编语言或者第三方线程库方能实现。atomic对于多线程编程,尤其是lock-free算法,其重要性不言而喻.
  • 并非所有的atomic内置类型操作均是lock-free的,与具体平台相关,可以调用is_lock_free接口进行查询。

2.thread详解

C++ thread库

3.mutex详解

C++ mutex库

4.future详解

c++ future库

5.conditon_variable详解

c++条件变量

6.atomic详解

c++ atomic库和atomic_flag库
CAS——Compare-and-swap

7.内存模型

non-blocking algorithm
c++ 内存模型
Memory Barriers: a Hardware View for Software Hackers

8.生产者消费者模型

你可能感兴趣的:(c++并发编程)