C++11新特性之线程std::call_once

news/2024/12/13 20:36:49/

C++ std::call_once

std::call_once 的定义与功能

std::call_once 是 C++11 标准引入的一种工具,用于确保某段代码只被执行一次,通常用于实现线程安全的单例模式或初始化操作。它结合了 std::once_flag 使用。

核心特点:

  1. 线程安全性:多个线程同时调用 std::call_once 时,只有一个线程会执行指定的代码,其余线程会等待该操作完成。
  2. 效率:只在首次调用时执行初始化代码,后续调用直接返回。

头文件:

需要包含 。

主要成员:

std::once_flag:
是一个辅助对象,用于记录是否已经执行过某段代码。
std::call_once:
负责调用指定的初始化函数,确保只执行一次。

用法

函数签名

template< class Callable, class... Args >
void std::call_once( std::once_flag& flag, Callable&& func, Args&&... args );
  1. flag:std::once_flag 对象,用于标记代码是否已被执行。
  2. func:可调用对象,表示需要执行的函数。
  3. args:传递给 func 的参数。

参考代码

以下代码演示如何使用 std::call_once 确保某段代码在多线程环境下只被执行一次:

#include <iostream>
#include <mutex>
#include <thread>// 声明一个 std::once_flag 对象
std::once_flag initFlag;// 定义需要执行的初始化函数
void initialize() {std::cout << "Initialization code executed by thread: " << std::this_thread::get_id() << std::endl;
}// 每个线程都调用这个函数
void threadFunction() {std::cout << "Thread " << std::this_thread::get_id() << " attempting to initialize..." << std::endl;// 确保初始化代码只执行一次std::call_once(initFlag, initialize);std::cout << "Thread " << std::this_thread::get_id() << " finished execution." << std::endl;
}int main() {// 启动多个线程std::thread t1(threadFunction);std::thread t2(threadFunction);std::thread t3(threadFunction);// 等待线程完成t1.join();t2.join();t3.join();return 0;
}

参考代码输出结果

Thread 140701600769792 attempting to initialize...
Initialization code executed by thread: 140701600769792
Thread 140701600769792 finished execution.
Thread 140701592377088 attempting to initialize...
Thread 140701592377088 finished execution.
Thread 140701583984384 attempting to initialize...
Thread 140701583984384 finished execution.
Thread 140266100016896 attempting to initialize...
Initialization code executed by thread: 140266100016896
Thread 140266100016896 finished execution.
Thread 140266083231488 attempting to initialize...
Thread 140266083231488 finished execution.
Thread 140266091624192 attempting to initialize...
Thread 140266091624192 finished execution.
Thread Thread 139840844814080 attempting to initialize...
Thread 139840853206784 attempting to initialize...
139840861599488 attempting to initialize...
Initialization code executed by thread: 139840861599488
Thread 139840861599488 finished execution.
Thread 139840844814080 finished execution.
Thread 139840853206784 finished execution.

注意事项

1. std::once_flag 是不可复制的:
必须以引用形式传递。
每个要初始化的独立任务都需要单独的 std::once_flag 对象。
2. std::call_once 的线程安全性:
使用低级同步原语(如原子操作)实现,性能较好。
3. 典型用例:
实现单例模式的线程安全初始化。
确保昂贵的初始化代码只运行一次。


http://www.ppmy.cn/news/1554844.html

相关文章

redis优化编码之字符串

redis 优化编码之字符串 ### 字符串优化 字符串对象是redis内部最常用的数据类型。 所有的键是字符串对象值对象除了整数之外都是使用字符串存储lpush cache:type "redis" "tair" "memcache" "leveldb"创建如上一个链表 需要创建一…

ubuntu 磁盘空间满,找不到占用文件的目录

解决方法&#xff1a; 检查磁盘空间&#xff1a; 执行 df -h 查看各分区磁盘使用情况。 查找大文件或目录&#xff1a; 执行 du -sh /* 2>/dev/null 查找根目录下的大文件或目录&#xff0c;再逐一进入子目录使用相同命令查找。 清理缓存和临时文件&#xff1a; 清理 /t…

2025年的大模型计划重点在于跨领域智能、工作流自动化、多模态能力强化

明年的计划和大模型发展方向可以围绕以下几个方面展开&#xff0c;结合实际应用场景和技术趋势&#xff0c;明确可执行的目标和期待的成果&#xff1a; 2025 年计划与展望&#xff1a;大模型能做些什么&#xff1f; 1. 更深层次的跨领域能力融合 目标&#xff1a;构建更强的跨…

ES前置定义和描述

目录 介绍说明全文检索倒排索引ES和Solr的对比数据结构&#xff08;存储非结构化数据&#xff09; 介绍说明 基于Apache Lucene构建的开源分布式搜索和分析引擎&#xff0c;专为处理大规模数据而设计。 java语言开发的web项目 全文检索 定义&#xff1a;一种非结构化数据的搜索…

github创建发布分支

创建一个名为 latest 的分支&#xff0c;并将其作为稳定版本分支。以下是操作步骤&#xff1a; 1. 创建 latest 分支 首先&#xff0c;确保你在 master 分支&#xff08;或当前的稳定版本分支&#xff09;上&#xff0c;并且已经提交了所有更改。然后&#xff0c;你可以创建一…

麒麟信安推出支持信创PC的新一代云桌面方案,助力政务信创高效安全运维

12月11日&#xff0c;在第二届国家新一代自主安全计算系统产业集群融通生态大会上&#xff0c;麒麟信安发布了支持信创PC的新一代云桌面方案&#xff0c;该方案是基于国际TCI架构实现国产PC机云化纳管在国内的首次发布&#xff0c;并与银河麒麟桌面操作系统、长城国产PC整机实现…

设计模式学习之——工厂模式

设计模式中的工厂模式主要分为三种&#xff1a;简单工厂模式&#xff08;Simple Factory Pattern&#xff09;、工厂方法模式&#xff08;Factory Method Pattern&#xff09;和抽象工厂模式&#xff08;Abstract Factory Pattern&#xff09;。 下面是对这三种工厂模式的详细…

360极速浏览器不支持看PDF

360安全浏览器采用的是基于IE内核和Chrome内核的双核浏览器。360极速浏览器是源自Chromium开源项目的浏览器&#xff0c;不但完美融合了IE内核引擎&#xff0c;而且实现了双核引擎的无缝切换。因此在速度上&#xff0c;360极速浏览器的极速体验感更佳。 展示自己的时候要在有优…