
并行和并发

并行和并发
并行基础
example
1 |
|
互斥量与临界区
std::mutex
是C++11中最基本的mutex类,通过实例化std::mutex
可以创建互斥量,而通过其成员函数lock()
可以进行上锁,unlock()
可以进行解锁。但在实际编写代码过程中,最好不去直接调用成员函数,因为调用函数就需要在每个临界区的出口处调用unlock()
;
RAII语法的模板类std::lock_guard
,保证了代码的异常安全性
example
1 | void critical_section(int change_v) { |
这样无论函数是正常返回还是中途抛出异常,都会引发堆栈回退(自动调用了
unlock
)
std::unique_lock
则是相对std::lock_guard
出现的,std::unique_lock
更加灵活,会以独占所有权的方式管理mutex对象上的上锁和解锁的操作
tips: std::lock_guard
不能显式的调用lock和unlock,而std::unique_lock
可以在声明后的任意位置调用,可以缩小锁的范围,提供更高的并发度
如果用到了std::condition_variable::wait
则必须使用std::unique_lock
作为参数
example
1 | void critical_section(int change_v) { |
期物
std::future
提供了一个访问异步操作结果的途径
对于下面这个问题
主线程A希望开辟一个线程B去执行某个我们预期的任务,并返回我一个结果;此时线程A可能正在忙其他的事情,无暇顾及B的结果,我们会希望在某个特定时间获得线程B的结果
C++11的std::future
被引入之前,通常的做法是:创建一个线程A,在线程A里启动任务B,当准备完毕后发送一个事件,并将结果保存在全局变量中。而主函数线程A里做其他的事情,当需要结果的时候,调用一个线程等待等待函数来获得执行的结果
example
1 | std::packaged_pack<int()> task([](){...}); // 将函数封装到task中 |
条件变量
条件变量std::condition_variable
是为了解决死锁而生,当互斥操作不够用时而引入的
在一个忙等待循环中可能会导致所有其他线程都无法进入临界区使得条件为真时,就会发生死锁