转自: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;
}
分享到:
相关推荐
编译时报 Looking for pthread_create - not found 的解决办法 linux gcc 编译时报Looking for pthread_create - not found 其解决办法是...
pthread_testcancel pthread_kill pthread_cancel 的使用例子
以下是对pthread_cond_wait的用法进行了详细的分析介绍,需要的朋友可以过来参考下
信号pthread_cond_wait信号pthread_cond_wait信号pthread_cond_wait信号pthread_cond_wait信号pthread_cond_wait
问题原因: pthread 库不是 Linux 系统默认的库,连接时需要使用静态库 libpthread.a,所以在使用pthread_create()创建线程,以及调用 pthread_atfork()函数建立fork处理程序时,需要链接该库。 问题解决: 在编译...
一篇博客内容 pthread_cond_wait详解
线程中处理信号pthread_sigmask 的使用
线程编程——使用pthread_join。 打包文件包含两个文件:c文件源代码、Makefile文件,运行环境在Ubuntu14.04下,使用自带的gcc编译器,同学们只需将文件夹复制到某一目录下之后在终端执行:1.“make”生成“test”可...
为什么在pthread_cond_wait()前要加一个while循环来判断条件是否为假呢?.zip
QT中多线程实例,使用C的pthread_create,传递参数,简单易懂,用工程和可执行程序及源代码,仅供参考
向线程函数传递参数的程序示例; 一个资源包,执行 tar zxvf example.tar.gz 解压资源; 复制readme.txt中的编译语句,编译得到可执行程序threadtest; ./threadtest 执行皆可看到效果。
主要介绍pthread_cread() 的介绍,便于自己学习和回顾。 如有错误欢迎指出。
visual studio多线程支持库,无法解析的外部符号 __imp__pthread_create,该符号在函数 _main 中被引用
2.2多线程介绍如果不能从根本上更新当前CPU的架构(在很长一段时间内还不太可能),那么继续提高CPU性能的方法就是超线程CPU模式 2.2.1多线程出现的原因
PThread header file
pthread资源包,pthread源码和已经编译好的VS2019_x64版本 #include <pthread.h> ...pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); pthread_create(&newThread, &attr, Function_t, NULL);
线程编程——不使用pthread_join。 打包文件包含两个文件:c文件源代码、Makefile文件,运行环境在Ubuntu14.04下,使用自带的gcc编译器,同学们只需将文件夹复制到某一目录下之后在终端执行:1.“make”生成“test”...
头文件 #include <pthread.h> 函数原形 pthread_t pthread_self();
pthread_kill测试,该函数可用来测试某个进程中的线程执行情况
32位android中bionic是32位的,其中的mutex只有一半也就是16位能够存储pid,当通过docker运行android时,大概率pid会超过16位的范围,就可能会导致android中mutex死锁,表现为应用卡住黑屏。 [32-bit ABI bugs]...