互斥元
在读写数据前锁定,读写后解锁。
#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();
}
本文介绍了C++中用于多线程同步的互斥锁(std::mutex)及其智能管理器std::lock_guard,展示了如何通过std::lock_guard实现RAII原则,确保资源在作用域内自动锁定和解锁。此外,还讨论了std::once_flag和std::call_once的使用,用于确保在多线程环境中数据只被初始化一次。这些工具对于保证线程安全和提高代码效率至关重要。
1816

被折叠的 条评论
为什么被折叠?



