互斥元
在读写数据前锁定,读写后解锁。
#include <mutex>
std::mutex m1;
m1.lock();
m1.unlock();
这样做有点麻烦,不符合面向对象的风格和RAII(资源获取就是初始化)的思路。c++、提供了std::lock_guard模板,在构造时会锁定传入的互斥元,析构时解锁相应的互斥元。
#include <mutex>
std::mutex m1;
void add(){
std::lock_guard<std::mutex > g1(m1);
do_sth();
}
锁和数据访问本质上时独立的,所以接口不能暴露被保护数据的指针。
只在初始化阶段进行保护
假如有一个构造起来很昂贵,但构造以后数据只读。c++提供了std::once_flag和std::call_once,每个线程都可以使用。到std::call_once返回时,指针会被摸一个线程初始化。
std::shared_ptr<int> int_ptr;
std::once_flag int_flag;
void init_int(){
int_ptr.reset(new int);
}
void foo(){
std::call_once(int_flag,init_int);//多个线程运行此函数,此处也只会被调用一次
do_sth();
}