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();
}
相关推荐
xlp666hub9 小时前
Leetcode 第三题:用C++解决最长连续序列
c++·leetcode
会员源码网10 小时前
构造函数抛出异常:C++对象部分初始化的陷阱与应对策略
c++
xlp666hub12 小时前
Leetcode第二题:用 C++ 解决字母异位词分组
c++·leetcode
不想写代码的星星13 小时前
static 关键字:从 C 到 C++,一篇文章彻底搞懂它的“七十二变”
c++
xlp666hub1 天前
Leetcode第一题:用C++解决两数之和问题
c++·leetcode
不想写代码的星星2 天前
C++继承、组合、聚合:选错了是屎山,选对了是神器
c++
不想写代码的星星3 天前
std::function 详解:用法、原理与现代 C++ 最佳实践
c++
樱木Plus4 天前
深拷贝(Deep Copy)和浅拷贝(Shallow Copy)
c++
blasit6 天前
笔记:Qt C++建立子线程做一个socket TCP常连接通信
c++·qt·tcp/ip
肆忆_7 天前
# 用 5 个问题学懂 C++ 虚函数(入门级)
c++