0

0

c++中的std::call_once是什么_c++保证函数仅执行一次的线程安全方法

裘德小鎮的故事

裘德小鎮的故事

发布时间:2025-12-09 11:15:31

|

315人浏览过

|

来源于php中文网

原创

std::call_once 可保证多线程中某段代码仅执行一次,配合 std::once_flag 实现线程安全的延迟初始化,适用于单例、全局资源配置等场景,相比手动加锁更安全高效,且要求被调用函数不抛异常。

c++中的std::call_once是什么_c++保证函数仅执行一次的线程安全方法

std::call_once 是 C++ 中用于保证某段代码在多线程环境下**只执行一次**的线程安全机制。它常用于实现延迟初始化,比如单例模式中的线程安全初始化,避免竞态条件和重复执行。

基本用法与原理

std::call_once 需要配合 std::once_flag 使用。once_flag 是一个标记,用来记录对应的操作是否已经执行过。每次调用 std::call_once 时,系统会检查该标记,只有首次调用会真正执行函数,其余线程会阻塞等待那次执行完成,之后直接返回。

示例代码:
#include 
#include 
#include 

std::once_flag flag;

void do_init() {
    std::cout << "初始化操作,仅执行一次\n";
}

void thread_func() {
    std::call_once(flag, do_init);
}

int main() {
    std::thread t1(thread_func);
    std::thread t2(thread_func);
    std::thread t3(thread_func);

    t1.join();
    t2.join();
    t3.join();

    return 0;
}

无论多少个线程调用 thread_funcdo_init 都只会被执行一次。

适用场景

std::call_once 特别适合以下情况:

通义万相
通义万相

通义万相,一个不断进化的AI艺术创作大模型

下载

立即学习C++免费学习笔记(深入)”;

  • 单例对象的线程安全初始化(Meyer 单例更简洁,但 call_once 提供更灵活的控制)
  • 全局资源的首次配置,如日志系统、数据库连接池的启动
  • 回调注册、信号处理设置等只需运行一次的逻辑

与其它机制对比

相比手动使用互斥锁加 if 判断的方式,std::call_once 更安全且高效:

  • 避免了“双重检查锁定”模式中可能的内存可见性问题
  • 不需要开发者手动管理锁的粒度和生命周期
  • 标准库内部做了优化,开销小,且确保唤醒所有等待线程

注意:传给 std::call_once 的函数不能抛出异常,否则程序会终止。如果初始化可能失败,应在函数内部处理异常,或使用状态变量标记失败。

基本上就这些。std::call_once 简洁、安全,是 C++ 多线程编程中实现“一次执行”语义的推荐方式。

相关专题

更多
if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

751

2023.08.22

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

481

2023.08.10

Python 多线程与异步编程实战
Python 多线程与异步编程实战

本专题系统讲解 Python 多线程与异步编程的核心概念与实战技巧,包括 threading 模块基础、线程同步机制、GIL 原理、asyncio 异步任务管理、协程与事件循环、任务调度与异常处理。通过实战示例,帮助学习者掌握 如何构建高性能、多任务并发的 Python 应用。

143

2025.12.24

数据库三范式
数据库三范式

数据库三范式是一种设计规范,用于规范化关系型数据库中的数据结构,它通过消除冗余数据、提高数据库性能和数据一致性,提供了一种有效的数据库设计方法。本专题提供数据库三范式相关的文章、下载和课程。

351

2023.06.29

如何删除数据库
如何删除数据库

删除数据库是指在MySQL中完全移除一个数据库及其所包含的所有数据和结构,作用包括:1、释放存储空间;2、确保数据的安全性;3、提高数据库的整体性能,加速查询和操作的执行速度。尽管删除数据库具有一些好处,但在执行任何删除操作之前,务必谨慎操作,并备份重要的数据。删除数据库将永久性地删除所有相关数据和结构,无法回滚。

2075

2023.08.14

vb怎么连接数据库
vb怎么连接数据库

在VB中,连接数据库通常使用ADO(ActiveX 数据对象)或 DAO(Data Access Objects)这两个技术来实现:1、引入ADO库;2、创建ADO连接对象;3、配置连接字符串;4、打开连接;5、执行SQL语句;6、处理查询结果;7、关闭连接即可。

347

2023.08.31

MySQL恢复数据库
MySQL恢复数据库

MySQL恢复数据库的方法有使用物理备份恢复、使用逻辑备份恢复、使用二进制日志恢复和使用数据库复制进行恢复等。本专题为大家提供MySQL数据库相关的文章、下载、课程内容,供大家免费下载体验。

255

2023.09.05

vb中怎么连接access数据库
vb中怎么连接access数据库

vb中连接access数据库的步骤包括引用必要的命名空间、创建连接字符串、创建连接对象、打开连接、执行SQL语句和关闭连接。本专题为大家提供连接access数据库相关的文章、下载、课程内容,供大家免费下载体验。

323

2023.10.09

PS使用蒙版相关教程
PS使用蒙版相关教程

本专题整合了ps使用蒙版相关教程,阅读专题下面的文章了解更多详细内容。

23

2026.01.19

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
10分钟--Midjourney创作自己的漫画
10分钟--Midjourney创作自己的漫画

共1课时 | 0.1万人学习

Midjourney 关键词系列整合
Midjourney 关键词系列整合

共13课时 | 0.9万人学习

AI绘画教程
AI绘画教程

共2课时 | 0.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号