简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长!
优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀
人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.
1.前言
本篇目的:理解线程局部存储TLS介绍.
2.线程局部存储TLS介绍
-
在Linux,TLS(Thread Local Storage)是一种机制,用于为每个线程提供独立的内存空间,以存储线程特定的数据。线程局部存储(TLS,Thread Local Storage)是一种编程技术,用于在多线程环境中为每个线程分配独立的内存空间,以存储线程特定的数据。通过使用线程局部存储,每个线程可以拥有独立的变量副本,而不会互相干扰。TLS 提供了解决这些问题的方法。
TLS 主要用于以下几个方面: -
- 线程安全:在多线程环境下,每个线程需要独立地维护自己的数据,例如线程私有的全局变量、错误状态、线程局部变量等。通过使用线程局部存储,可以避免多个线程同时访问共享变量时产生的竞争条件和数据不一致性问题。
-
- 提高性能:线程局部存储可以提高多线程程序的性能,因为每个线程可以直接访问自己的数据,而不需要通过锁来保护共享变量的访问。这可以减少锁竞争和线程间的同步开销。
-
- 管理全局状态:某些情况下需要在线程间共享全局状态,但又需要保证线程安全。TLS 可以用来管理线程私有的全局状态,从而实现线程间共享全局状态的需求。
-
- 线程局部存储使得多线程程序能够更加高效和安全地处理线程间的数据隔离和共享问题。
3.两种方式来实现线程局部存储
-
- POSIX 线程库:在 POSIX 线程库中,可以使用 pthread 库提供的函数 pthread_key_create、pthread_setspecific 和 pthread_getspecific 来创建和管理线程局部存储。
-
- GCC 编译器内建函数:GCC 编译器提供了 __thread 关键字,用于声明线程局部变量。使用这个关键字声明的变量会为每个线程创建独立的副本。
-
3.Linux 的 TLS 机制通常通过操作系统和编译器的协作来实现。在编译器层面,使用 __thread 关键字声明的变量会被编译成特定的指令,以实现线程局部存储。在操作系统层面,内核会负责分配和管理线程的 TLS 存储空间,以确保每个线程可以独立地访问自己的变量副本。
特别值得一提的是,TLS 在 Linux 下的实现一般涉及到与编译器和链接器的配合,因为在不同的架构和编译器下,TLS 的具体实现机制可能有所不同。
-4. Linux 中的 TLS 机制提供了一种有效的方式来管理线程局部存储,使得多线程程序能够更加高效地处理线程间的数据隔离和共享问题。
4.代码实例
1.通过pthread库实现线程局部存储
#include <iostream>
#include <pthread.h>
pthread_key_t key;
void* threadFunc(void* arg) {
int* value = new int(42);
// 将数据存储到线程局部存储中
pthread_setspecific(key, value);
// 从线程局部存储中取出数据
std::cout << "Thread-local value: " << *((int*)pthread_getspecific(key)) << std::endl;
return NULL;
}
int main() {
// 创建线程局部存储的键
pthread_key_create(&key, NULL);
pthread_t thread1, thread2;
// 创建线程
pthread_create(&thread1, NULL, threadFunc, NULL);
pthread_create(&thread2, NULL, threadFunc, NULL);
// 等待线程结束
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
// 删除线程局部存储的键
pthread_key_delete(key);
return 0;
}
2. 通过__thread关键字实现线程局部存储
#include <iostream>
// 通过__thread关键字实现线程局部存储
__thread int tls_var = 42;
void* threadFunc(void* arg) {
// 打印线程局部存储中的数据
std::cout << "Thread-local value: " << tls_var << std::endl;
return NULL;
}
int main() {
pthread_t thread1, thread2;
// 创建线程
pthread_create(&thread1, NULL, threadFunc, NULL);
pthread_create(&thread2, NULL, threadFunc, NULL);
// 等待线程结束
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
return 0;
}
3.通过C++11标准中的thread_local关键字实现线程局部存储
#include <iostream>
#include <thread>
thread_local int tls_var = 42;
void threadFunc() {
// 打印线程局部存储中的数据
std::cout << "Thread-local value: " << tls_var << std::endl;
}
int main() {
// 创建线程
std::thread thread1(threadFunc);
std::thread thread2(threadFunc);
// 等待线程结束
thread1.join();
thread2.join();
return 0;
}