C语言之pthread_once实例总结(八十三)

news2024/11/23 19:32:17

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长!

优质专栏:Audio工程师进阶系列原创干货持续更新中……】🚀

人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.

更多原创,欢迎关注:Android系统攻城狮

欢迎关注Android系统攻城狮

1.前言

本篇目的:理解pthread_once函数用法

2.pthread_once函数介绍

  • pthread_once函数是POSIX线程库中的一个函数,用于在单线程环境中进行线程安全的初始化。该函数确保仅在第一次调用时执行给定的初始化代码,而不会重复执行。这对于需要在程序启动时进行初始化,但只执行一次的操作非常有用。

函数原型如下:

int pthread_once(pthread_once_t *once_control, void (*init_routine)(void));

参数说明:

  • pthread_once函数保证init_routine函数在多线程环境下只被调用一次。
  • once_control是一个用来控制init_routine函数是否被调用的控制变量。
  • init_routine是需要保证只调用一次的函数。

函数返回值:

  • 如果函数成功执行,返回0。
  • 如果函数失败,返回一个非零值。

使用pthread_once的基本步骤如下:

  1. 定义一个pthread_once_t类型的变量,并将其初始化为一个特定的值(通常是PTHREAD_ONCE_INIT)。这个值用于标识初始化状态。
  2. 在需要初始化的代码之前调用pthread_once函数,并将初始化的函数作为参数传递给它。
  3. 确保只调用pthread_once函数一次,因为在每次调用时都会重置初始化状态标识符。

3.代码实例

1.使用pthread_once初始化全局变量

#include <iostream>
#include <pthread.h>

int global_var = 0; // 全局变量

void init_once() {
    std::cout << "Initializing global variable..." << std::endl;
    global_var = 42; // 初始化全局变量
    std::cout << "Global variable initialized." << std::endl;
}

int main() {
    pthread_once_t once = PTHREAD_ONCE_INIT;
    pthread_once(&once, init_once);
    std::cout << "Main thread: global_var = " << global_var << std::endl;
    return 0;
}

2.使用pthread_once初始化线程安全的资源

#include <iostream>
#include <pthread.h>
#include <mutex>

std::mutex mtx; // 互斥锁
int shared_var = 0; // 共享变量

void init_once() {
    std::cout << "Initializing shared variable..." << std::endl;
    shared_var = 42; // 初始化共享变量
}

int main() {
    pthread_once_t once = PTHREAD_ONCE_INIT;
    pthread_once(&once, init_once);
    std::cout << "Main thread: shared_var = " << shared_var << std::endl;
    // 在这里可以使用共享变量进行线程安全的操作,例如读写锁的使用等。
    return 0;
}

3.使用pthread_once保护静态成员初始化

#include <iostream>
#include <pthread.h>

class MyClass {
public:
    static void* initialize() {
        // 静态成员初始化代码
        return nullptr;
    }
};

int main() {
    pthread_once_t once = PTHREAD_ONCE_INIT;
    pthread_once(&once, MyClass::initialize);
    MyClass::doSomething();
    return 0;
}

4.使用 pthread_once 完成一次性初始化一个全局变量

#include <iostream>
#include <pthread.h>

使用pthread_once函数来确保线程池的初始化。pthread_once_t once_control = PTHREAD_ONCE_INIT;
int global_var = 0;

void init_global_var() {
    global_var = 42;
}

void* thread_function(void*) {
   
static bool stop = false; // 用于标记是否停止线程池的标志位。 pthread_once(&once_control, init_global_var);
    std::cout << "Global variable in thread: " << global_var << std::endl;
    return nullptr;
}

int main()当stop为true时,会停止所有正在执行的任务并退出所有正在运行的线程。 {
    pthread_t thread1, thread2;
    pthread_create(&thread1,使用pthread_once函数来确保标志位的初始化 nullptr, thread_function, nullptr);
    pthread_create(&thread2, nullptr, thread_function, nullptr);
    pthread_join(thread1, nullptr);
    pthread_join(thread2, nullptr);
    std::cout << "Global variable in main: " << global_var << std::endl;
    return 0;
}

5. 使用 pthread_once 确保只有一个线程执行初始化函数

#include <iostream>
#include <pthread.h>

pthread_once_t once_control = PTHREAD_ONCE_INIT;

void init_once_function() {
    std::cout << "Initialization function called" << std::endl;
}

void* thread_function(void*) {
    pthread_once(&once_control, init_once_function);
    std::cout << "Thread function completed" << std::endl;
    return nullptr;
}

int main() {
    pthread_t thread1, thread2;
    pthread_create(&thread1, nullptr, thread_function, nullptr);
    pthread_create(&thread2, nullptr, thread_function, nullptr);
    pthread_join(thread1, nullptr);
    pthread_join(thread2, nullptr);
    return 0;
}

6.使用 pthread_once 初始化多个静态变量

#include <iostream>
#include <pthread.h>

void init_static_vars() {
    static int static_var1 = 10;
    static int static_var2 = 20;

    std::cout << "Static variables initialized: " << static_var1 << " and " << static_var2 << std::endl;
}

void* thread_function(void*) {
    pthread_once_t once_control = PTHREAD_ONCE_INIT;
    pthread_once(&once_control, init_static_vars);
    return nullptr;
}

int main() {
    pthread_t thread1, thread2;
    pthread_create(&thread1, nullptr, thread_function, nullptr);
    pthread_create(&thread2, nullptr, thread_function, nullptr);
    pthread_join(thread1, nullptr);
    pthread_join(thread2, nullptr);
    return 0;
}

7.使用 pthread_once 初始化一个全局对象

#include <iostream>
#include <pthread.h>

class GlobalObject {
public:
    void showMessage() {
        std::cout << "Hello from global object" << std::endl;
    }
};

pthread_once_t once_control = PTHREAD_ONCE_INIT;
GlobalObject* global_object = nullptr;

void init_global_object() {
    global_object = new GlobalObject();
}

void* thread_function(void*) {
    pthread_once(&once_control, init_global_object);
    global_object->showMessage();
    return nullptr;
}

int main() {
    pthread_t thread1, thread2;
    pthread_create(&thread1, nullptr, thread_function, nullptr);
    pthread_create(&thread2, nullptr, thread_function, nullptr);
    pthread_join(thread1, nullptr);
    pthread_join(thread2, nullptr);
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1184331.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ClickHouse介绍和使用

ClickHouse介绍和使用 1. 简介2. ClickHouse特点3. 数据类型3.1. 整型3.2. 浮点型3.3. Decimal型3.4. 布尔型3.5. 字符串3.6. 枚举类型3.7. 时间类型 4. 表引擎4.1. TinyLog4.2. Memory4.3. MergeTree4.3.1. partition by分区&#xff08;可选&#xff09;4.3.2. primary key 主…

微信小程序将后端返回的图片文件流解析显示到页面

说明 由于请求接口后端返回的图片格式不是一个完整的url,也不是其他直接能显示的图片格式&#xff0c;是一张图片 后端根据模板与二维码生成图片,返回二进制数据 返回为文件流的格式,用wx.request请求的时候&#xff0c;就自动解码成为了下面这样的数据数据格式,这样的数据没…

Spring的缓存机制-循环依赖

群公告 Java每日大厂面试题&#xff1a; 1、Spring 是如何解决循环依赖&#xff1f; 答案&#xff1a;三级缓存&#xff0c;简单来说&#xff0c;A创建过程中需要B&#xff0c;于是A将自己放到三级缓存里面&#xff0c;去实例化B&#xff0c;B实例化的时候发现需要…

智能AI系统ChatGPT系统源码+支持GPT4.0+支持ai绘画(Midjourney)/支持OpenAI GPT全模型+国内AI全模型

一、AI创作系统 SparkAi创作系统是基于OpenAI很火的ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如…

交流负载发电机测试

交流负载发电机测试是一种常用的测试方法&#xff0c;用于评估发电机在负载条件下的性能和稳定性。测试过程中需要使用负载设备模拟实际负载&#xff0c;并通过测量电压、电流、功率等参数来评估发电机的输出能力和稳定性。 在进行测试之前&#xff0c;首先需要准备好测试设备和…

30张图详解IP地址网络知识

你们好&#xff0c;我的网工朋友。 IP地址是所有网络初级课程里最先涉及到的技术点&#xff0c;对于IP地址的合理规划是网络设计的重要环节&#xff0c;必须拿捏。 IP地址规划的好坏&#xff0c;影响到网络路由协议算法的效率&#xff0c;影响到网络的性能&#xff0c;影响到网…

短剧出海火爆,Flat Ads独家流量助泛娱乐赛道App迅速获客增长

10月26日&#xff0c;由扬帆出海主办的GICC2023 | 第四届全球互联网产业CEO大会正式圆满落幕&#xff0c;Flat Ads等出海企业应邀参加。 据悉&#xff0c;本届GICC深圳站邀请200CXO行业领袖、300各路优质厂商、1200全球互联网产业代表共聚一堂&#xff0c;聚焦短剧、游戏、泛娱…

最前端|如何使用Plausible实现页面埋点?

目录 一、业务背景 二、业务场景描述 三、解决方案 //如何集成 Plausible &#xff1f; //如何监控特定功能使用情况&#xff1f; 什么是 MyEventName? //如何向自定义事件传递参数&#xff1f; 一、业务背景 随着公司自研产品的不断发展&#xff0c;对前端页面的监控和…

强力解决使用node版本管理工具 NVM 出现的问题(找不到 node,或者找不到 npm)

强力解决使用node版本管理工具 NVM 出现的问题&#xff08;找不到 node&#xff0c;或者找不到 npm&#xff09; node与npm版本对应关系 nvm是好用的Nodejs版本管理工具&#xff0c; 通过它可以方便地在本地调换Node版本。 2020-05-28 Node当前长期稳定版12.17.0&#xff0c;…

适用于Linux桌面歌词应用程序MusixMatch

导读Musixmatch桌面应用程序可用于Linux&#xff01;不是Linux用户缺少桌面歌词应用程序。包括“即时歌词”和“Lyricfier”&#xff0c;许多开源音乐播放器都会运用某种歌词集成。 但是Musixmatch应用程序与那些有点不同。 Musixmatch的USP是Syncronized歌词 如果您曾经使用…

如何选择高效率的在线分板机主轴?

随着智能移动设备和其他电子3C设备需求的增大&#xff0c;PCB分板机的需要也随之而大增。越来越多的企业开始使用在线分板机来替代传统的手工分板&#xff0c;从而提升了生产效率&#xff0c;提高了产品质量&#xff0c;降低了生产成本。在分板机设备中&#xff0c;高速主轴是关…

Pandas数据预处理Pandas合并数据集在线闯关_头歌实践教学平台

这里写目录标题 第1关 Concat与Append操作第2关 合并与连接第3关 案例&#xff1a;美国各州的统计数据 第1关 Concat与Append操作 任务描述 本关任务&#xff1a;使用read_csv()读取两个csv文件中的数据&#xff0c;将两个数据集合并&#xff0c;将索引设为Ladder列&#xff0…

92. 递归实现指数型枚举

题目 思路 因为有n个数&#xff0c;每个数选或不选都是一种方案&#xff0c;而且要递增输出&#xff0c;那么就标记每个数是否备选&#xff0c;然后判断完n个数以后&#xff0c;就可以输出了 代码 #include<bits/stdc.h> using namespace std; int n; bool f[100] {0…

WEB渲染模式——CSR SSR SSG ISR DPR区别

页面渲染 浏览器渲染页面&#xff0c;根据HTML文档类型声明&#xff08;DOCTYPE&#xff09;解析HTML和CSS&#xff0c;渲染步骤&#xff1a;解析、样式计算、元素布局、绘制、重绘重排。HTML、CSS、JavaScript是网页的三大核心技术。 HTML (Hyper Text Markup Language) 超文…

【沐风老师】3dMax快速平铺纹理插件QuickTiles教程

QuickTiles是3ds max的一个插件&#xff0c;允许您将常规瓷砖纹理转换为交互式纹理&#xff0c;就在mat.editor中。 换言之&#xff0c;您可以根据需要对任何纹理进行修改和重新创建&#xff1a;更改布局、瓷砖大小、格式、颜色、接缝、体积、随机化形状或纹理等等。 这种方法大…

eNsp下如何使用wireshark抓包

文章目录 拓扑图抓包操作 拓扑图 抓包操作 可以通过下图上的指示 来设置 Time列的显示样式。 这里有个缺点就是就是抓取ensp上的虚拟设备上的数据包时的&#xff0c;年月日时间显示的不对。暂时无解决办法。 一般选择 日期和时间&#xff08;日期和时间与当前标准时间对应上时…

集简云平台助力无代码开发,实现平安银行与电商平台、CRM系统的快速连接

无代码开发与平安银行 平安银行是中国内地首家公开上市的全国性股份制银行&#xff0c;经过多年发展&#xff0c;已经在科技引领、综合金融、零售转型等领域形成独特竞争力和鲜明经营特色。近年来&#xff0c;平安银行更是积极拥抱科技&#xff0c;为此&#xff0c;选择了与集…

智慧工地源码 手册文档 app 数据大屏、硬件对接、萤石云

智慧工地解决方案依托计算机技术、物联网、云计算、大数据、人工智能、VR、AR等技术相结合&#xff0c;为工程项目管理提供先进技术手段&#xff0c;构建工地现场智能监控和控制体系&#xff0c;弥补传统方法在监管中的缺陷&#xff0c;最终实现项目对人、机、料、法、环的全方…

CROS错误 403 preflight 预检

预检 403 响应 Response for preflight 403 forbidden 如上图&#xff0c;配置了请求接口一直报错&#xff0c;前端看了没有什么问题&#xff0c;不知道哪里报错了&#xff0c;那么可能是后端没有设置跨域。&#xff08;或者是设置了&#xff0c;但是可能需要换一种方式&#…

C语言每日一题(26)

力扣网 203. 移除链表元素 题目描述 给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回 新的头节点 。 思路分析 针对如图的普通情况&#xff0c;不能简单的遍历到对应位置然后进行释放&#xff0c;一方…