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;
}

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

从TCP到Socket,彻底理解网络编程是怎么回事

进行程序开发的同学&#xff0c;无论Web前端开发、Web后端开发&#xff0c;还是搜索引擎和大数据&#xff0c;几乎所有的开发领域都会涉及到网络编程。比如我们进行Web服务端开发&#xff0c;除了Web协议本身依赖网络外&#xff0c;通常还需要连接数据库&#xff0c;而数据库连…

Java中对象的比较:复写基类的equals+Comparble接口类的比较+比较器比较+PriorityQueue的比较+源码分析

文章目录 Java中对象的比较一、元素的比较二、对象的比较1.复写基类的equals2.基于Comparble接口类的比较3.基于比较器比较三种方法的对比 4. 集合框架中PriorityQueue的比较方式 Java中对象的比较 一、元素的比较 在Java中&#xff0c;基本类型的对象可以直接比较大小。 二、…

【Python3】【力扣题】232. 用栈实现队列

【力扣题】题目描述&#xff1a; 栈&#xff1a;线性集合。后进先出。 队列&#xff1a;线性集合。先进先出。 【Python3】代码&#xff1a; 解题思路&#xff1a;两个栈&#xff0c;一个入队的栈&#xff0c;一个出队的栈。出栈时&#xff0c;若出队的栈为空&#xff0c;才将…

RabbitMQ 死信队列

在MQ中&#xff0c;当消息成为死信&#xff08;Dead message&#xff09;后&#xff0c;消息中间件可以将其从当前队列发送到另一个队列中&#xff0c;这个队列就是死信队列。而在RabbitMQ中&#xff0c;由于有交换机的概念&#xff0c;实际是将死信发送给了死信交换机&#xf…

c语言 结构体 简单实例

结构体 简单例子 要求&#xff1a; 结构体保存学生信息操作 代码 #include <stdio.h>//定义结构体 struct student{int ID;char name[20];char sex;char birthday[8];int grade; };int main(){int number;printf("请输入学生个数&#xff1a;");scanf(&quo…

lua中的循环 while、for、repeat until三种循环方式、pairs和ipairs区别

lua中的循环 while、for、repeat until三种循环方式、pairs和ipairs区别 介绍for循环参数ipairs和pairs whilerepeat until总结 介绍 这里我用while、for、repeat until分别输出1-20之间的奇数 &#xff0c;具体的语法可以看下面的代码 for循环 参数 定义一个初始值为start…

ARM64 linux并发与同步之原子操作

卷2&#xff1a;调试与案例分析 第一章 并发与同步 画了两张简图&#xff0c;方便理解&#xff0c;如下&#xff1a; 针对并发源的问题&#xff0c;我接触的项目中都是SMP系统&#xff0c;目前大部分也都是SMP系统&#xff1b; 对于SMP系统&#xff0c;情况会更复杂。 □ 同…

Servlet详解

一.Servlet生命周期 初始化提供服务销毁 1.测试生命周期 package com.demo.servlet;import javax.servlet.*; import java.io.IOException;public class LifeServlet implements Servlet {Overridepublic void init(ServletConfig servletConfig) throws ServletException {…

ros的安装和rosdep的初始化操作

ros的安装 安装ROS完整桌面版安装&#xff08;Desktop-Full&#xff09;环境配置rosdep初始化 安装ROS完整桌面版安装&#xff08;Desktop-Full&#xff09; 官网 选择思想者乌龟 选择ubuntu平台 操作 开始安装ROS 完整桌面版安装&#xff08;Desktop-Full&#xff0c;推荐…

小白学爬虫:手机app分享商品短连接获取淘宝商品链接接口|淘宝淘口令接口|淘宝真实商品链接接口|淘宝商品详情接口

通过手机APP分享的商品短链接&#xff0c;我们可以调用相应的接口来获取淘口令真实URL&#xff0c;进而获取到PC端的商品链接及商品ID。具体步骤如下&#xff1a; 1、通过手机APP分享至PC端的短链接&#xff0c;调用“item_password”接口。 2、该接口将返回淘口令真实URL。 3…

如何规划并新建大数据平台的独立生产域?5步走

一般来说&#xff0c;大数据平台包括以下4类数据生产域——生产生态环境&#xff08;正式生产环境&#xff09;、开发和测试环境、培训和演示环境、灾备环境。各生产域在由平台提供资源、安全、监控、故障恢复等保障的同时&#xff0c;不同的生产域之间还需要严格隔离&#xff…

基于生成对抗网络的照片上色动态算法设计与实现 - 深度学习 opencv python 计算机竞赛

文章目录 1 前言1 课题背景2 GAN(生成对抗网络)2.1 简介2.2 基本原理 3 DeOldify 框架4 First Order Motion Model5 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 基于生成对抗网络的照片上色动态算法设计与实现 该项目较为新颖&am…