1. 什么是并发
在计算机中,并发是指单个系统并行运行多个独立的活动,而不是一个接着一个的顺序执行。
任务切换与硬件并发:任务切换是指单核系统通过划分时间片来模拟并发,而硬件并发是指多核系统实现真正意义上的并行,但是在多核系统上也会用到任务切换。
上下文切换:存储当前运行任务的CPU状态和寄存器状态,然后切换到要执行的任务,之后通过加载存储的状态恢复之前的任务。这有一定的时间开销。
2. 并发的方法
2.1 多进程并发
划分任务到多个单线程的进程中。
缺点:
- 由于操作系统有很多保护,多进程之间通信比较复杂
- 进程要比线程占用更多的资源
优点:
- 更容易写成并发安全的代码
- 通过多进程并发可以让通过网络连接的不同设备进行通信
2.2 多线程并发
在单个进程中运行多个线程。
优点:
- 资源花费更少
- 由于相同进程的不同线程共享内存空间,可以方便进行交流
缺点:
- 并发安全难以实现
3. 为什么使用并发
- 分离概念(更加符合单一职责原则)
- 提高性能
什么时候不要使用并发:总的来说就是收益小于代价。比如有时候上下文带来的开销还有大于并发可以得到的收益;还有线程是有限的资源,更多的线程也意味着操作系统管理将付出更多代价
4. C++中的并发
C++98不支持并发
通过C语言API来实现并发,比如POSIX C,还是Microsoft Windows API
C++的一些开源库,比如Boost, ACE等,提出一个关键概念:RAII(Resource Acquisition Is Initialization,资源获取即初始化)
C++11开始在语言层面支持并发,包括线程管理,保护共享数据,同步操作,原子操作。
通常建议使用C++11之后的标准库来开发并发程序,除非对性能有极致追求,场景比较特定等情况。
5. Hello World例子
#include <iostream>
#include <thread> //头文件
/**
* @brief 线程初始函数
*/
void hello()
{
std::cout<<"Hello Concurrent World\n";
}
int main()
{
std::thread t(hello); //新建一个线程
t.join(); //等待子线程运行结束,加入式
}
分析:
创建线程(初始函数)
父线程等待子线程