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();
}
相关推荐
可均可可12 分钟前
C++之OpenCV入门到提高004:Mat 对象的使用
c++·opencv·mat·imread·imwrite
杨荧27 分钟前
【JAVA毕业设计】基于Vue和SpringBoot的服装商城系统学科竞赛管理系统
java·开发语言·vue.js·spring boot·spring cloud·java-ee·kafka
白子寰34 分钟前
【C++打怪之路Lv14】- “多态“篇
开发语言·c++
小芒果_0139 分钟前
P11229 [CSP-J 2024] 小木棍
c++·算法·信息学奥赛
gkdpjj44 分钟前
C++优选算法十 哈希表
c++·算法·散列表
王俊山IT1 小时前
C++学习笔记----10、模块、头文件及各种主题(一)---- 模块(5)
开发语言·c++·笔记·学习
为将者,自当识天晓地。1 小时前
c++多线程
java·开发语言
-Even-1 小时前
【第六章】分支语句和逻辑运算符
c++·c++ primer plus
小政爱学习!1 小时前
封装axios、环境变量、api解耦、解决跨域、全局组件注入
开发语言·前端·javascript
k09331 小时前
sourceTree回滚版本到某次提交
开发语言·前端·javascript