call_once与once_flag实现线程安全初始化
请说明std::call_once和std::once_flag的用法,以及它们相比双重检查锁定的优势。
回答
我是大山
call_once保证某个函数指针在多个线程中仅被执行一次,即使出现异常也会重试。
std::once_flag flag;
void init() { /* 初始化操作 */ }
// 多线程安全
std::call_once(flag, init);
相比双重检查锁定(DCLP),call_once的优势:
- 标准库内部实现,无需手写复杂的DCLP逻辑
- 自动处理异常回滚
- 无需担心C++内存模型下的指令重排问题
- 性能经过精心优化(通常使用无锁实现)