当前位置: 首页 > article >正文

C++: std::once_flag 和 std::call_once

std::once_flag 和 std::call_once

std::once_flag 和 std::call_once 是 C++11 引入的同步原语,用于确保某个函数在多线程环境中只被执行一次。它们位于 头文件中,主要用于实现线程安全的初始化操作。

std::once_flag

概述

类型:std::once_flag 是一个结构体,用于记录某个函数是否已经被调用过。
用途:与 std::call_once 配合使用,确保某个函数在多线程环境中只被执行一次。

std::once_flag my_flag;

std::call_once

函数:std::call_once 是一个函数模板,用于确保某个函数在多线程环境中只被执行一次。

参数:
std::once_flag& flag:一个 std::once_flag 对象,用于记录函数是否已经被调用过。

Function&& f:要执行的函数或可调用对象。

Args&&… args:传递给函数的参数。

std::once_flag my_flag;

void initialize() {
    // 初始化代码
}

void some_function() {
    std::call_once(my_flag, initialize);
}

示例代码

以下是一个完整的示例,展示了如何使用 std::once_flag 和 std::call_once 来确保某个函数在多线程环境中只被执行一次:

#include <iostream>
#include <mutex>
#include <thread>

std::once_flag my_flag;

void initialize() {
    std::cout << "Initialization code executed" << std::endl;
}

void thread_function() {
    std::call_once(my_flag, initialize);
}

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

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

    return 0;
}

底层实现

std::once_flag 和 std::call_once 的底层实现依赖于操作系统提供的同步机制,通常使用互斥锁(mutex)和条件变量(condition variable)来确保线程安全。

std::once_flag

std::once_flag 内部维护一个状态,用于记录函数是否已经被调用过。
这个状态通常是一个原子变量(atomic variable),确保在多线程环境下的操作是原子的。


std::call_once

std::call_once 内部使用一个互斥锁来保护对 std::once_flag 状态的访问。
如果函数尚未被调用,std::call_once 会锁定互斥锁,执行函数,然后更新 std::once_flag 的状态。
如果函数已经被调用,std::call_once 会立即返回,不会再次执行函数。

http://www.kler.cn/a/291272.html

相关文章:

  • 结构化日志和集中日志服务
  • Agentic RAG 解释
  • spring mvc源码学习笔记之九
  • 论文导读 | 数据库中的连接操作
  • TensorRT-LLM中的MoE并行推理
  • 代码随想录 链表 test 5
  • Web前端 lucky-canvas【大转盘 九宫格 老虎机】抽奖插件(适用JS/TS、Vue、React、微信小程序、Uniapp和Taro)
  • 数据结构单向 循环 双向 链表的插入 删除 查询
  • 数据结构与算法-C语言复习
  • 【Kubernetes知识点问答题】Pod 调度
  • Cesium 实战 - 自定义纹理材质 - 流动线(精灵线)
  • 后端开发刷题 | 数组中的逆序对
  • 深入理解 Go 中的 defer、panic 、日志管理与WebAssembly
  • 另一种关于类的小例
  • 模拟经营研究(三):雷霆双雄之《奥比岛 》
  • 公共DNS大测评,哪个解析性能最好?
  • JAVA学习-练习试用Java实现“基本计算器”
  • ES可以干什么?安装ES
  • turbovnc 服务端、客户端安装
  • 河南建筑装饰工程设计专项资质办理机构怎样选
  • 【数据结构】二叉树顺序存储结构堆的应用以及解决TOP-K问题
  • 微信小程序 跳转
  • `Android NDK` `readelf` 在`Terminal`上的使用(配置`readelf`)
  • Behind the Code:与 Rakic 和 Todorovic 对话 OriginTrail 如何实现 AI 去中心化
  • python文件自动分类(3)
  • 【代码随想录|图论part03之后】