线程局部变量
来源:互联网 发布:傲盾网络加速器免费版 编辑:程序博客网 时间:2024/06/16 13:20
学习java的时候,有个thread_local变量,表示是线程局部的变量。
unix中介绍到了这个的内容:
主要是用到了一个pthread_key_t变量来维护。
以下是一个程序:启动多个线程,每个线程都保存一些k-v内容。k相等,但是v不同。
每个线程的buf的格式如下:
前面4个字节是一个int,表示总共有多少条记录;
紧接着的4个字节是一个int,表示buf有效的总长度(包括头部本身);
然后就是具体的每条记录的内容了。
每个记录的格式又为:
前面4个字节为该记录总长度,接着4个字节为k的长度,接着是k的内容,接着是v的内容。
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <stdlib.h>
static pthread_key_t key;
static pthread_once_t init_done=PTHREAD_ONCE_INIT;
pthread_mutex_t env_mutex=PTHREAD_MUTEX_INITIALIZER;
extern char** environ;
char* gval[5]={"hello","world","hi","zhuli","good"};
int arg_len=8192;//buf length
int thread_cnt=1;
static void thread_init(void){
pthread_key_create(&key,free);//这个key只初始化一次
}
char * getenv(const char* name){
int i,len;
char *envbuf;
pthread_t tid=pthread_self();
printf("in thread ,tid=%d\n",tid);
pthread_once(&init_done,thread_init);//只初始化一次
pthread_mutex_lock(&env_mutex);
envbuf=(char*)pthread_getspecific(key);
if(envbuf==NULL){
envbuf=(char*)malloc(arg_len);
if(envbuf==NULL){
pthread_mutex_unlock(&env_mutex);
return (NULL);
}
pthread_setspecific(key,envbuf);
}
len=strlen(name);
int find=0;
for(i=0;environ[i]!=NULL;i++){
// printf("tid:%d,%s\n",tid,environ[i]);
if(strncmp(name,environ[i],len)==0 && environ[i][len]=='='){
strcpy(envbuf,&environ[i][len+1]);
//pthread_mutex_unlock(&env_mutex);
//return (envbuf);
find=1;
}
}
pthread_mutex_unlock(&env_mutex);
if(find==1)
return envbuf;
return NULL;
}
//save thread local data
//first 4byte:rec count
//second 4 byte:rec length(include head info)
void putdata(const void* k,void *val){
const char* pre="\n----------putdata-------";
char * buf=(char *)pthread_getspecific(key);
int rec_cnt=0;
int buf_len=0;
if(buf==NULL){
printf("%s empty buf\n",pre);
buf=malloc(arg_len);
pthread_setspecific(key,buf);
}else{
rec_cnt=*((int*)buf);
buf_len=*((int*)(buf+4));
printf("%s rec_cnt=%d,rec_len=%d\n",pre,rec_cnt,buf_len);
}
char * nk=(char*)k;
int klen=strlen(k);
char *nv=(char*)val;
int vlen=strlen(nv);
printf("k=%s,v=%s,klen=%d,vlen=%d\n",nk,nv,klen,vlen);
//char buf[klen+vlen+6];
//total len
//first 4byte:total len,next 4byte:klen,next key cont,next val cont;
int total_len=klen+vlen+4+4;
printf("total len=%d,0x%xH\n",total_len,total_len);
//length of record
int index=buf_len==0?8:buf_len;//start position of this key-value pair
buf[index++]=total_len;
buf[index++]=total_len>>8 ;//little endien
buf[index++]=total_len>>16;
buf[index++]=total_len>>24;
printf("buf[0]=0x%xH,buf[1]=0x%xH,buf[2]=0x%xH,buf[3]=0x%xH\n",buf[buf_len+0],buf[buf_len+1],buf[buf_len+2],buf[buf_len+3]);
//length of this key
buf[index++]=klen;
buf[index++]=klen>>8;
buf[index++]=klen>>16;
buf[index++]=klen>>24;
int i=0;
//fill key content
for(i=0;i<klen;i++){
printf("%c",nk[i]);
buf[index++]=nk[i];
}
//fill value content
for(i=0;i<vlen;i++){
buf[index++]=nv[i];
}
//modify whole buf rec_cnt,and length
rec_cnt++;
buf_len+=total_len;
buf[0]=rec_cnt;
buf[1]=rec_cnt>>8;
buf[2]=rec_cnt>>16;
buf[3]=rec_cnt>>24;
buf[4]=buf_len;
buf[5]=buf_len>>8;
buf[6]=buf_len>>16;
buf[7]=buf_len>>24;
printf("%s,after save data:rec_cnt:%d,buf_len=%d\n",pre,*((int*)buf),*((int*)(buf+4)));
}
//获取k对应的内容
void * getdata(const char* k){
char *pre="\n------getdata-----";
char *buf=pthread_getspecific(key);
if(buf==NULL){
printf("%sis empty\n",pre);
return (NULL);
}
int rec_cnt=*((int*)(buf));
int buf_len=*((int*)(buf+4));
printf("%s,rec_cnt=%d,buf_len=%d\n",pre,rec_cnt,buf_len);
//loop
int rec_offset=8;
int *p=(int*)(buf+rec_offset);
int *keylp=(int*)(buf+rec_offset+4);
int find=0;
int res=0;
while(1){
res=strncmp(k,*((char*)(buf+rec_offset+8)),*keylp);
if(!res){
find=1;
//未写完
char resbuf[];
}
}
}
//线程入口函数
void * thread_entry(void * arg){
const char* pre="\n--------thread_entry---------";
pthread_once(&init_done,thread_init);
// getenv("SHELL");
pthread_t tid=pthread_self();
int *index=(int*)arg;
printf("%stid=%d,index=%d,val=%s\n",pre,tid,*index,gval[*index]);
putdata("str",gval[*index]);
putdata("smile","do it now");
}
void main(){
pthread_t tid[thread_cnt];
int i=0;
int idx[thread_cnt];
for(;i<thread_cnt;i++){
idx[i]=i;
pthread_create(&tid[i],NULL,&thread_entry,idx+i);
}
sleep(5);
}
- DLL:线程局部变量
- TLS线程局部变量
- 线程局部变量ThreadLocal
- ThreadLocal 线程局部变量
- 线程局部变量
- 线程局部变量
- 线程局部变量ThreadLocal
- 线程局部变量
- ThreadLocal线程局部变量
- 线程局部变量ThreadLocal
- 线程局部变量ThreadLocal
- ThreadLocal 线程局部变量
- ThreadLocal 线程局部变量
- 线程-ThreadLocal-线程局部变量
- 局部变量线程安全测试
- 再谈线程局部变量
- 理解ThreadLocal(线程局部变量)
- 线程局部变量与 __thread
- JavaScript 作用域链图详解
- 条件随机场(CRF)的一篇不错ppt
- C++ 中进制间转换
- MPI 枚举排序实现
- java.lang.ClassNotFoundException: org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAnd
- 线程局部变量
- 第5条:避免创建不必要的对象
- 一、创建物料组件:BAPI_NETWORK_COMP_ADD
- 字符串反转实验
- 一篇谈论Scrum的好文章,值得一看
- oracle 创建空间全文索引失败
- POJ 1269 Intersecting Lines(线段相交,水题)
- Java调用C++类库--JNI
- 赞一下TMS Software 和 AdvStringGrid