转自:http://www.douban.com/note/162329664/
面说一下线程中特有的线程存储, Thread Specific Data
。线程存储有什么用了?他是什么意思了?大家都知道,在多线程程序中,所有线程共享程序中的变量。现在有一全局变量,所有线程都可以使用它,改变它的值。
而如果每个线程希望能单独拥有它,那么就需要使用线程存储了。表面上看起来这是一个全局变量,所有线程都可以使用它,而它的值在每一个线程中又是单独存储
的。这就是线程存储的意义。
下面说一下线程存储的具体用法。
l 创建一个类型为 pthread_key_t 类型的变量。
l
调用 pthread_key_create() 来创建该变量。该函数有两个参数,第一个参数就是上面声明的
pthread_key_t 变量,第二个参数是一个清理函数,用来在线程释放该线程存储的时候被调用。该函数指针可以设成 NULL
,这样系统将调用默认的清理函数。
l 当线程中需要存储特殊值的时候,可以调用 pthread_setspecific() 。该函数有两个参数,第一个为前面声明的 pthread_key_t 变量,第二个为 void* 变量,这样你可以存储任何类型的值。
l 如果需要取出所存储的值,调用 pthread_getspecific() 。该函数的参数为前面提到的 pthread_key_t 变量,该函数返回 void * 类型的值。
下面是前面提到的函数的原型:
int pthread_setspecific(pthread_key_t key, const void *value);
void *pthread_getspecific(pthread_key_t key);
int pthread_key_create(pthread_key_t *key, void (*destructor)(void*));
下面是一个如何使用线程存储的例子:
#include <malloc.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
static pthread_key_t log_key;
void write_log(const char* msg){
FILE* fp = (FILE*)pthread_getspecific(log_key);
fprintf(fp, "get a msg:%s\n", msg);
}
void* thread_func(void* args){
static int cnt = 0;
char fn[32];
//要在当前目录创建log子目录,否则创建文件会失败
//sprintf(fn, "log/thread.%d.log", (unsigned int)pthread_self());
sprintf(fn, "log/thread.%d.log", ++cnt);
FILE* fp = fopen(fn, "w");
if(!fp){
fprintf(stderr, "open file %s error !\n", fn);
return NULL;
}
pthread_setspecific(log_key, fp);
char msg[64];
sprintf(msg, "I am %s\n", fn);
write_log(msg);
}
void close_log_file(void* log_file){
fclose((FILE*)log_file);
}
int main(){
const int n = 10;
pthread_t pids[n];
pthread_key_create(&log_key, close_log_file);
for(int i = 0; i < n; i++){
pthread_create(pids+i, NULL, thread_func, NULL);
}
for(int i = 0; i < n; i++){
pthread_join(pids[i], NULL);
}
return 0;
}
分享到:
相关推荐
线程局部存储是一种为每个线程分配独立变量的方法,使用`pthread_key_create()`和`pthread_getspecific() / pthread_setspecific()`等函数实现。 八、性能和调试 多线程编程需要考虑上下文切换开销、死锁、饥饿等...
本文将深入探讨PThread的核心概念、主要函数和使用方法,以帮助读者理解并掌握这一强大的多线程工具。 1. **线程基础** - **线程与进程**:线程是进程中的一个执行单元,同一进程内的线程共享相同的内存空间,而...
其中,第一个参数是用于接收创建新的线程的 id,第二个参数是用于设置线程的属性,一般设置为 NULL,表示使用线程默认属性,第三个参数是函数指针,用于设置线程的主函数,当 pthread_create 函数返回时,则会自动...
本文档总结了 Posix Pthread API 的主要函数和使用方法,旨在帮助开发者快速掌握 Posix Pthread API 的使用。 一、 基本线程编程 在 Posix Pthread API 中,线程是轻量级的进程,可以并发执行以提高系统性能。创建...
- `pthread_key_create(pthread_key_t *key, void (*destructor)(void *))`: 创建一个线程私有数据键。 - `pthread_key_delete(pthread_key_t key)`: 删除一个线程私有数据键。 **2.2 私有数据的访问** - `pthread...
本手册将详细讲解每个线程函数的使用方法、参数设置、返回值等信息,从而帮助开发者更好地掌握 LINUX 线程编程技术。 一、线程创建 线程创建是 LINUX 线程编程的基础,pthread_create 函数是创建线程的主要函数。...
在NDK中,可以使用`pthread_key_create()`创建TLS键,然后使用`pthread_setspecific()`和`pthread_getspecific()`来设置和获取线程局部变量。 ```c #include <pthread.h> pthread_key_t tls_key; void cleanup...
在Linux中,可以使用pthread_key_create、pthread_getspecific和pthread_setspecific函数来创建和管理线程局部存储。 总结来说,Linux线程间同步涉及多种机制,根据实际需求选择合适的方法。理解并熟练掌握这些同步...
通过实际案例,如线程池、服务器并发处理等,深入理解PTHREAD的使用方法和注意事项,了解如何在SUN系统中有效地设计和实现多线程程序。 通过学习这个"UNIX下多线程编程指南",你将能够熟练地运用PTHREAD API,解决...
2. 创建和注销:`pthread_key_create()`用于创建线程私有数据键,`pthread_key_delete()`用于删除不再使用的键。每个线程通过键来访问其私有数据,`pthread_getspecific()`和`pthread_setspecific()`分别用于获取和...
- `pthread_key_create()`和`pthread_getspecific()`、`pthread_setspecific()`用于创建和访问线程局部存储,每个线程拥有独立的数据存储空间。 7. **线程取消** - `pthread_cancel()`函数可以请求取消一个线程,...
- 示例代码通常包括一个简单的线程函数,该函数在新线程中执行,并使用`pthread_create`创建线程,使用`pthread_join`等待线程完成。 ##### 分离线程 - 线程可以被分离,这意味着它们可以在没有父线程等待的情况下...
- 使用`pthread_key_create()`创建TLS键,`pthread_setspecific()`和`pthread_getspecific()`来存储和获取线程特有的数据。 5. **线程调度** - Linux默认使用公平调度策略,但可以通过`pthread_setschedparam()`...
7. **线程安全的函数封装**:pthreads-w32还提供了一些线程安全的函数,如线程安全的动态内存管理函数(pthread_once()、pthread_key_create()等),确保在多线程环境中正确执行。 在实际应用中,开发人员可以通过...
7. **线程局部存储**:`pthread_key_create()`和`pthread_getspecific()`、`pthread_setspecific()`函数可用于创建线程局部存储,这是一种在线程间隔离数据的方法,每个线程都有自己的副本。 8. **线程安全**:在多...
使用`pthread_key_create()` 和 `pthread_getspecific()` 创建和获取线程局部存储,为每个线程提供私有数据,无需同步。 通过深入学习《pthreads Primer》,开发者可以掌握如何在C语言环境下利用pthreads进行高效...
9. **线程局部存储**:使用`pthread_key_create()`和`pthread_getspecific()`来创建和获取线程局部变量,为每个线程提供独立的数据存储。 10. **错误处理**:了解`pthread`函数的错误返回值,如EAGAIN、EINVAL等,...