c++ call_once 使用详解

c++ call_once 使用详解

std::call_once

  • 头文件 #include <mutex>

  • 函数原型:

    cpp 复制代码
    template<class Callable, class... Args>
    void call_once(std::once_flag& flag, Callable&& f, Args&&... args);
    • flag:标志对象,用于指示 f 是否已调用过。
    • f:要调用的可调用对象。
    • args:传递给 f 的参数。
  • 作用:保证可调用对象 f 只被执行一次,即使同时从多个线程调用。

  • 注意事项:

    • 如果在调用 std::call_once 的时刻,flag 指示 f 已经调用过,那么 std::call_once 会立即返回。
    • 如果在调用 f 时抛出了异常,那么异常将传播给 std::call_once 的调用方,并且 flag 不会被翻转。
    • 如果调用正常返回,那么 flag 被翻转,并保证以同一 flag 对 std::call_once 的其他调用立即返回。
    • 如果有多个线程同时在 flag 未翻转时调用 std::call_once,那么这些调用将被组成单独全序,并被依次执行。

示例代码

cpp 复制代码
#include <cstdio>
#include <mutex>
#include <thread>

std::once_flag flag1, flag2;

void simple_do_once()
{
    std::call_once(flag1, []() { printf("only call once\n"); });
}

void may_throw_function(bool do_throw)
{
    if (do_throw) {
        printf("throw, try again...\n");
        throw std::exception();
    }
    printf("no throw, call once\n");
}

void do_once(bool do_throw)
{
    try {
        std::call_once(flag2, may_throw_function, do_throw);
    } catch (...) {
    }
}

int main()
{
    std::thread st1(simple_do_once);
    std::thread st2(simple_do_once);
    st1.join();
    st2.join();

    std::thread t1(do_once, true);
    std::thread t2(do_once, false);
    std::thread t3(do_once, true);
    t1.join();
    t2.join();
    t3.join();
}
相关推荐
rit843249910 分钟前
基于MATLAB的环境障碍模型构建与蚁群算法路径规划实现
开发语言·算法·matlab
lang2015092814 分钟前
Java JSR 250核心注解全解析
java·开发语言
Wpa.wk17 分钟前
接口自动化测试 - 请求构造和响应断言 -Rest-assure
开发语言·python·测试工具·接口自动化
czhc114007566325 分钟前
协议 25
java·开发语言·算法
春夜喜雨29 分钟前
关于内存分配的优化与设计
c++·tcmalloc·malloc·jemallc
ae_zr30 分钟前
QT动态编译应用后,如何快速获取依赖
开发语言·qt
gjxDaniel33 分钟前
Kotlin编程语言入门与常见问题
android·开发语言·kotlin
范纹杉想快点毕业36 分钟前
状态机设计与嵌入式系统开发完整指南从面向过程到面向对象,从理论到实践的全面解析
linux·服务器·数据库·c++·算法·mongodb·mfc
坚定学代码1 小时前
认识 ‘using namespace‘
c++
jiang_changsheng1 小时前
环境管理工具全景图与深度对比
java·c语言·开发语言·c++·python·r语言