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

简介: 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;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

史上最全最新Ubuntu20.04安装教程(图文)

总的来说&#xff0c;安装Ubantu包含以下三个步骤&#xff1a; 一、安装虚拟机 二、Ubuntu镜像下载 三、虚拟机配置 一、安装虚拟机 选择安装VMware Workstation&#xff0c;登录其官网下载安装包&#xff0c;链接如下&#xff1a; 下载 VMware Workstation Pro​www.vmwa…

设计模式之--原型模式(深浅拷贝)

原型模式 缘起 某天&#xff0c;小明的Leader找到小明:“小明啊&#xff0c;如果有个发简历的需求&#xff0c;就是有个简历的模板&#xff0c;然后打印很多份&#xff0c;要去一份一份展示出来&#xff0c;用编程怎么实现呢&#xff1f;” 小明一听&#xff0c;脑袋里就有了…

ARM64 linux并发与同步之内存屏障

1.2 内存屏障 1.2.1 概念理解 原理部分比较苦涩难懂&#xff0c;我们先不过多详细介绍这部分的由来和经过&#xff0c;接下来着重讲解什么用途和实现&#xff1b; ARM64架构中提供了3条内存屏障指令。 数据存储屏障(Data Memory Barrier, DMB)指令。数据同步屏障(Data Synch…

劲松HPV防治诊疗中心发布:HPV感染全面防治解决方案

在当今社会&#xff0c;HPV(人乳头瘤病毒)感染问题已成为广大公众关注的焦点。作为一种高度传染性的病毒&#xff0c;HPV感染不仅可能导致生殖器疣&#xff0c;还可能引发各种癌症。面对这一严重威胁&#xff0c;劲松HPV防治诊疗中心以其专业的医疗团队、正规的治疗流程和全方位…

Python基础入门例程51-NP51 列表的最大与最小(循环语句)

最近的博文&#xff1a; Python基础入门例程50-NP50 程序员节&#xff08;循环语句&#xff09;-CSDN博客 Python基础入门例程49-NP49 字符列表的长度-CSDN博客 Python基础入门例程48-NP48 验证登录名与密码&#xff08;条件语句&#xff09;-CSDN博客 目录 最近的博文&…

函数极限求解方法归纳

1、连续函数直接代入值&#xff08;加减不可以部分代入值&#xff09; 例题1 配凑构造等价无穷小 等价无穷小 注意&#xff1a;不要在加减中部分使用等价无穷小&#xff0c;可以利用拆极限的方式求&#xff0c;拆出来的每一部分都要有极限&#xff0c;如果有一部分没有极限就是…

STM32F4X定时器之通用定时器

一、STM32通用定时器概述 通用定时器包括一个16位或32位自动重载计数器&#xff0c;可通过可编程预分频器进行驱动。定时器可以实现多种功能&#xff0c;包括测量输入信号的脉冲宽度和生成输出波形&#xff0c;通过使用定时器预分频器和RCC时钟控制器预分频器&#xff0c;可以…

目标检测——Yolo系列(YOLOv1/2/v3/4/5/x/6/7/8)

目标检测概述 什么是目标检测&#xff1f; 滑动窗口&#xff08;Sliding Window&#xff09; 滑动窗口的效率问题和改进 滑动窗口的效率问题&#xff1a;计算成本很大 改进思路 1&#xff1a;使用启发式算法替换暴力遍历 例如 R-CNN&#xff0c;Fast R-CNN 中使用 Selectiv…

C++算法:完美矩形

题目 给你一个数组 rectangles &#xff0c;其中 rectangles[i] [xi, yi, ai, bi] 表示一个坐标轴平行的矩形。这个矩形的左下顶点是 (xi, yi) &#xff0c;右上顶点是 (ai, bi) 。 如果所有矩形一起精确覆盖了某个矩形区域&#xff0c;则返回 true &#xff1b;否则&#xf…

AI 绘画 | Stable Diffusion WebUI的基本设置和插件扩展

前言 Stable Diffusion WebUI是一个基于Gradio库的浏览器界面&#xff0c;用于配置和生成AI绘画作品&#xff0c;并且进行各种精细地配置。它支持目前主流的开源AI绘画模型&#xff0c;例如NovelAI/Stable Diffusion。 在基本设置方面&#xff0c;Stable Diffusion WebUI的默…

asp.net外卖网站系统VS开发mysql数据库web结构c#编程Microsoft Visual Studio

一、源码特点 asp.net外卖网站系统 是一套完善的web设计管理系统&#xff0c;系统采用mvc模式&#xff08;BLLDALENTITY&#xff09;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为vs2010&#xff0c;数据库为mysql&#xff0c;使用c#语…

Git的原理与使用(一)

目录 Git初始 Git安装 Git基本操作 创建git本地仓库 配置git 工作区,暂存区,版本库 添加文件,提交文件 查看.git文件 修改文件 版本回退 小结 Git初始 git是一个非常强大的版本控制工具.可以快速的将我们的文档和代码等进行版本管理. 下面这个实例看理解下为什么需…

CountDownLatch和CyclicBarrier详解

1. CountDownLatch 1.1 简介 CountDownLatch 是 Java 中并发包&#xff08;java.util.concurrent&#xff09;提供的一种同步工具&#xff0c;用于在多线程环境中协调多个线程之间的执行顺序。它的作用是允许一个或多个线程等待其他线程完成操作。 CountDownLatch 通过一个计…

java使用geotools导出shp文件

SHP格式是一种矢量数据格式&#xff0c;用于存储地理信息系统&#xff08;GIS&#xff09;数据。 SHP文件由一系列有序的文件组成&#xff0c;我们导出的shp文件包括.shp、.shx、.dbf、.prj以及.fix文件。 .shp&#xff08;shape&#xff09;文件&#xff1a;存储矢量地图数据&…

自定义类型:联合和枚举

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 前言 1. 联合体 1.1 联合体类型的声明 1.2 联合体的特点 1.3 相同成员的结构体和联合体对比 1.4 联合体大小的计算 1.5 联合的一个练习 2. 枚举类型 2.1 枚举类型的声明…

思维模型 目标效应

本系列文章 主要是 分享 思维模型&#xff0c;涉及各个领域&#xff0c;重在提升认知。明确目标&#xff0c;激发内在动机。 1 目标效应的应用 1.1 目标效应在教育领域的应用-棉花糖实验 美国斯坦福大学心理学系的教授米歇尔&#xff08;Walter Mischel&#xff09;曾经进行了…

1204. 错误票据

题目&#xff1a; 1204. 错误票据 - AcWing题库 思路&#xff1a; 将输入的数据存入数组&#xff0c;从小到大排序后遍历&#xff0c;若 (a[i] a[i - 1])res1 a[i]--->重号;若(a[i] - a[i - 1] > 2)res2 a[i] - 1--->断号。 难点&#xff1a;题目只告诉我们输入…

1977 智慧校园平台开发与实现JSP【程序源码+文档+调试运行】

摘要 本文旨在设计和实现一个智慧校园平台系统&#xff0c;以满足管理员、教师和学生三类用户的需求。管理员拥有最高管理权限&#xff0c;可对教师和学生用户进行管理&#xff1b;教师用户可查看和管理本班学生信息、成绩等&#xff1b;学生用户可查看个人信息、考试成绩等。…

Leetcode139单词拆分及其多种变体问题

1 声明 1.1 首先&#xff0c;大家常常把这道题当作了背包问题来做&#xff0c;因为其循环结构和背包问题刚好相反&#xff0c;但事实如此嘛&#xff1f; 背包问题通常都是组合问题&#xff0c;这其实是一道“”面向目标值的排列问题“&#xff0c;具体和背包问题有什么不同可…

[01]汇川IMC30G-E系列运动控制卡应用笔记

简介 IMC30G-E系列产品是汇川技术自主研制的高性能EtherCAT网络型运动控制器&#xff08;卡&#xff09;&#xff0c;同时兼容脉冲轴的控制&#xff1b;IMC30G-E支持点位/JOG、插补、多轴同步、高速位置比较输出、PWM等全面的运动控制功能&#xff0c;具备高同步控制精度。 开发…