举报的网站是国外的域名和空间,广西麒铭建设有限公司网站,谷歌搜索引擎363,樟木头电子网站建设报价std::call_once 是 C11 标准库中提供的一个线程安全的一次性调用机制#xff0c;位于 mutex 头文件中。它用于确保在多线程环境中#xff0c;某个函数#xff08;或可调用对象#xff09;仅被调用一次#xff0c;无论有多少线程尝试调用它。这种机制常用于实现线程…std::call_once 是 C11 标准库中提供的一个线程安全的一次性调用机制位于 mutex 头文件中。它用于确保在多线程环境中某个函数或可调用对象仅被调用一次无论有多少线程尝试调用它。这种机制常用于实现线程安全的单例模式、延迟初始化等场景。 核心机制
依赖 std::once_flag 需要与 std::once_flag 配合使用once_flag 用于标记某个操作是否已被执行。线程安全 多个线程调用 std::call_once 时最终只有一个线程会实际执行目标函数其他线程会被阻塞直到目标函数执行完毕。 基本语法
#include mutexstd::once_flag flag; // 必须全局或共享void initialize() {// 仅执行一次的初始化逻辑
}void thread_func() {std::call_once(flag, initialize); // 保证 initialize() 只执行一次
}典型应用场景
1. 线程安全的单例模式
class Singleton {
public:static Singleton getInstance() {std::call_once(init_flag, []() {instance.reset(new Singleton());});return *instance;}// 禁止拷贝和赋值Singleton(const Singleton) delete;Singleton operator(const Singleton) delete;private:Singleton() default; // 私有构造函数~Singleton() default;static std::unique_ptrSingleton instance;static std::once_flag init_flag;
};// 静态成员初始化
std::unique_ptrSingleton Singleton::instance;
std::once_flag Singleton::init_flag;2. 延迟初始化
class Resource {
public:void load() { /* 耗时的初始化操作 */ }
};Resource* global_resource nullptr;
std::once_flag resource_flag;void initResource() {global_resource new Resource();global_resource-load();
}void useResource() {std::call_once(resource_flag, initResource); // 按需初始化// 使用 global_resource...
}关键特性
线程安全 std::call_once 内部通过锁或原子操作保证线程安全无需手动管理互斥量。异常处理 如果被调用的函数抛出异常该异常会传播到调用线程且 once_flag 不会被标记为“已执行”其他线程可能会再次尝试执行。若需确保函数仅执行一次即使抛出异常需在函数内部处理异常。 性能优化 仅第一次调用需要同步后续调用无锁性能接近直接访问。比双重检查锁定Double-Checked Locking更简洁安全。 注意事项
once_flag 的生命周期 std::once_flag 必须与目标函数的调用周期一致通常声明为 static 或全局变量。不可复用 一个 once_flag 只能用于一次初始化操作。不同初始化逻辑需使用不同的 once_flag。C11 后的单例简化写法 对于单例模式C11 起局部静态变量的初始化是线程安全的因此可以更简洁地实现Singleton Singleton::getInstance() {static Singleton instance; // C11 保证线程安全return instance;
}但 std::call_once 在需要动态初始化或复杂逻辑时仍然有用。 与双重检查锁定的对比
传统双重检查锁定DCLP
Singleton* Singleton::instance nullptr;
std::mutex mtx;Singleton* Singleton::getInstance() {if (instance nullptr) { // 第一次检查std::lock_guardstd::mutex lock(mtx);if (instance nullptr) { // 第二次检查instance new Singleton();}}return instance;
}缺点需手动管理锁且在某些内存模型下可能出现未定义行为如指令重排序。优势std::call_once 更简洁且无隐患。 总结
适用场景单例模式、全局配置加载、资源按需初始化等。核心价值简化多线程环境下的“一次性操作”实现避免手动管理锁和竞态条件。性能接近无锁操作适合高频调用场景。