

新闻资讯
技术学院std::call_once 是 C++11 提供的线程安全机制,确保某函数在多线程下仅执行一次,需配合 std::once_flag 使用;flag 必为静态生命周期,异常不标记完成,性能优于手动 mutex,语义清晰且异常安全。
std::call_once 是 C++11 引入的线程安全工具,用于确保某个函数(或可调用对象)在多线程环境下**只被执行一次**,即使多个线程同时调用它。它常和 std::once_flag 配合使用,是实现线程安全单次初始化(如单例、资源首次加载、全局状态设置等)的核心机制。
必须成对使用:
std::once_flag 实例。once_flag& 和一个可调用对象(支持函数指针、lambda、bind、成员函数等),以及可选参数。它会阻塞其他竞争线程,直到该可调用对象成功执行完毕——且仅有一个线程真正执行,其余线程等待后直接返回。比如加载配置、创建线例、初始化日志系统:
std::shared_ptrg_config; std::once_flag g_config_init_flag; void init_config() { g_config = std::make_shared ("config. json"); } // 多个线程可能同时调用这个函数 std::shared_ptr
get_config() { std::call_once(g_config_init_flag, init_config); return g_config; }
无论多少线程并发调用 get_config(),init_config() 只运行一次,g_config 初始化安全无竞态。
立即学习“C++免费学习笔记(深入)”;
std::once_flag 必须是 static 或具有静态生命周期(如全局、类 static 成员),否则每次调用都新建 flag,失去“一次”的语义。std::call_once 会捕获并重新传播给当前线程;但该次调用被视为“失败”,flag 不置位——下次调用仍会尝试执行(即:异常 ≠ 已完成)。相比手动用 mutex 加锁做单次检查:
基本上就这些。用好 std::call_once,能帮你避开大量多线程初始化的坑。