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();
}
相关推荐
白杨尚青1 小时前
C++进阶篇(二):多态——虚函数、重写、虚函数表与三个经典坑(附完整代码仓库)
开发语言·c++·多态·虚函数·重写·动态绑定
syagain_zsx2 小时前
spdlog实战:日志分级、滚动与性能调优
linux·c++·日志库·二次开发日志库
WJ.Polar19 小时前
Java封装、继承、多态
java·开发语言
摇滚侠19 小时前
Java 中如何表示负数,有符号和无符号的区别,补码的计算规则,char byte short int long 的范围
java·开发语言
weixin_3077791320 小时前
C++代码实现MATLAB中的fitrtree函数功能
开发语言·c++·算法·matlab
AI wins20 小时前
c++新增頭文件
c++
Shadow(⊙o⊙)20 小时前
仿muduo实现高并发服务器——事件就绪管理Channel.hpp
服务器·c++
爱读书的小胖20 小时前
Codewars:Rot13(C)解题分析
c语言·开发语言
鸽鸽程序猿20 小时前
【项目】【在线判题系统】b端题目增删改
开发语言·python
by2099920 小时前
哈希表——快速找到数据:冲突、删除与扩容的实现
数据结构·c++·哈希算法·散列表