简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长!
优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀
人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.
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
的基本步骤如下:
- 定义一个pthread_once_t类型的变量,并将其初始化为一个特定的值(通常是PTHREAD_ONCE_INIT)。这个值用于标识初始化状态。
- 在需要初始化的代码之前调用pthread_once函数,并将初始化的函数作为参数传递给它。
- 确保只调用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;
}