Pthread
来源:互联网 发布:手甲钩淘宝 编辑:程序博客网 时间:2024/06/18 17:50
Pthread - 线程特定数据(thread-specified data)
在 Pthread 中,线程特定数据(thread-specified data,以下简称 TSD)是绑定由pthread_key_create()函数创建的 key 的属于调用线程自身的数据。简单地说就是一个全局变量可以被多个线程访问,但是在每个线程中该全局变量指向由本线程设定的值,而且每个线程都可以通过该全局变量访问到本线程设定的值,彼此互不干扰。以下是操作 TSD 的函数:
void *pthread_getspecific(pthread_key_t key); int pthread_setspecific(pthread_key_t key, const void *value); int pthread_key_create(pthread_key_t *key, void (*destructor)(void *)); int pthread_key_delete(pthread_key_t key);
以下为测试程序:
#include <unistd.h>#include <errno.h>#include <pthread.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#define NUM_THREADS 2#define ERROR(func, no) { \ fprintf(stderr, "%s: %s\n", func, strerror(no)); \ exit(EXIT_FAILURE); \ }pthread_key_t key_tsd;typedef struct tsd { pthread_t tid; // thread ID char *str; //} tsd_t;pthread_once_t once_control = PTHREAD_ONCE_INIT;void destory_routine(void* value) { printf("destory ...\n"); free(value); //delete dynamic storage allocated to each TSD}void init_routine() { int ret; ret = pthread_key_create(&key_tsd, destory_routine); if(ret) { ERROR("pthread_key_create", ret); } printf("Thread-specified data key initialized\n");}void* thread_routine(void *arg) { //key will be initialized twice //pthread_once_t once_control = PTHREAD_ONCE_INIT; pthread_once(&once_control, init_routine); // make sure initialization actually only run once pthread_t tid = pthread_self(); tsd_t* val = (tsd_t*)malloc(sizeof(tsd_t)); val->tid = tid; val->str = (char*)arg; pthread_setspecific(key_tsd, val); printf("Thread %#lx set thread-specific data: %p\n", (size_t)tid, val); val = pthread_getspecific(key_tsd); printf("Thread %#lx get thread-specific data: %s\n", (size_t)val->tid, val->str); sleep(2); val = pthread_getspecific(key_tsd); printf("Thread %#lx get thread-specific data: %s\n", (size_t)val->tid, val->str); pthread_exit(NULL);}int main(int argc, char** argv){ int ret, i; pthread_t tid[NUM_THREADS]; pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); if((ret=pthread_create(&tid[0], &attr, thread_routine, "Thread 1"))){ ERROR("pthread_create", ret); } if((ret=pthread_create(&tid[1], &attr, thread_routine, "Thread 2"))){ ERROR("pthread_create", ret); } pthread_attr_destroy(&attr); for(i=0; i<NUM_THREADS; ++i) { ret = pthread_join(tid[i], NULL); if(ret) { ERROR("pthread_join", ret); } } pthread_key_delete(key_tsd); exit(EXIT_SUCCESS);}
运行效果:
从程序的运行结果可以看出:两线程通过相同的可以访问到本线程的特定数据,并且程序中特意 sleep 一段时间后再次访问 TSD 结果不变,进一步验证 TSD 的特性。值得注意的是上述程序中调用了 pthread_once 函数来创建 pthread_key_t
变量,程序的运行结果可以发现该 key 只被初始化了一次,这是通过设置 pthread_once 函数的 once_control 参数实现的,而且要注意该参数的生存周期应为整个程序的运行周期,也就是说该参数应是一个全局变量或静态局部变量。而 destroy_routine 调用了两次,释放了各自线程为 TSD分配的动态内存。
once_control为局部变量, key被初始化两次:
0 0
- Pthread
- pthread
- pthread
- PThread
- pthread
- pthread
- pthread
- pthread
- pthread
- pthread
- pthread
- pthread
- pthread
- pthread
- Pthread
- pthread
- pthread
- Pthread
- JAVA自定义业务异常BusinessException
- JavaScript之原型
- 中国开源项目哪家强?看看阿里,百度,腾讯,360等都开...
- Chrome调整CSS盒模型自动生成代码
- JDK8 lambda表达式
- Pthread
- 分类算法-----决策树(ID3)算法原理和Python实现
- UGUI和NGUI多个按钮事件方法(for循环添加)
- linux nobody用户是什么 nobody用户介绍
- Android 中的属性动画 --- 1(基本用法)
- extjs-3.4.1多选下拉框实现
- 蓝桥杯:幸运数
- CodeForces 23B Party (思维题)
- SSM(十三) 将dubbo暴露出HTTP服务