有时会需要这种模式,一个全局变量,需要在程序的任何地方都可以使用它,但是当这个变量出现在不同线程时,就要求系统将这个变量拷贝到各个线程中,这样的话,每个线程内部也可以随时访问本线程的全局变量,但是线程之间的这个变量没有任何关系。这样就避免了锁,会提高程序运行的效率。在java中是ThreadLocal, 在boost中是
thread_specific_ptr。
在linux下C的方法是 _thread
//a.h
#ifndef __A_H
#define __A_H
#include <string>
using namespace std;
class A {
public:
string s;
int i;
};
#endif
//c.h
#ifndef __C_H
#define __C_H
//#include <boost/thread/tss.hpp>
#include "a.h"
#include <pthread.h>
#include <unistd.h>
//using namespace boost;
class C {
public:
//static thread_specific_ptr<A> pool;
static __thread A *pool;
static void init() {
pool = new A();
}
/*static __thread A *instance() {
pool = new A();
return pool;
} */
};
__thread A *C::pool;
#endif
//list.h
#ifndef __LIST_H
#define __LIST_H
#include "c.h"
class list
{
public:
int start;
int step;
list(int s,int t):start(s), step(t){
C::init();
C::pool->i = s;
}
void inc() {
C::pool->i += step;
}
int get() {
return C::pool->i;
}
};
#endif
//main.cpp
#include "c.h"
#include "list.h"
#include <iostream>
#include <pthread.h>
#include <unistd.h>
using namespace std;
int i = 1;
int s = 1;
void *run(void *junk) {
list ls(i, s);
for (int ind = 0; ind < 10; ++ind) {
cout << (size_t)pthread_self() << ": "<< ls.get()<<endl;
ls.inc();
sleep(2);
// cout << (size_t)pthread_self() << ": "<< ls.get()<<endl;
}
}
int main() {
pthread_t t_a, t_b;
pthread_create(&t_a, NULL, run, (void *)NULL);
sleep(2);
i += 1000;
s = 5;
pthread_create(&t_b, NULL, run, (void*)NULL);
pthread_join(t_a, NULL);
pthread_join(t_b, NULL);
return 0;
}
output:
1085499712: 1
1095989568: 1001
1085499712: 2
1095989568: 1006
1085499712: 3
1095989568: 1011
1085499712: 4
1095989568: 1016
1085499712: 5
1095989568: 1021
1085499712: 6
1095989568: 1026
1085499712: 7
1095989568: 1031
1085499712: 8
1095989568: 1036
1085499712: 9
1095989568: 1041
1085499712: 10
1095989568: 1046
如果将c.h中的__thread都注释掉的,数据就不一致了:
1110722880: 1
1110722880: 2
1121212736: 1001
1121212736: 1006
1110722880: 1011
1121212736: 1012
1110722880: 1017
1121212736: 1018
1110722880: 1023
1121212736: 1024
1110722880: 1029
1121212736: 1030
1110722880: 1035
1121212736: 1036
1110722880: 1041
1121212736: 1042
1110722880: 1047
1121212736: 1048
1110722880: 1053
1121212736: 1054
如果用boost,更简单
//c.h
#ifndef __C_H
#define __C_H
#include <boost/thread/tss.hpp>
#include "a.h"
#include <pthread.h>
#include <unistd.h>
using namespace boost;
class C {
public:
static thread_specific_ptr<A> pool;
//static __thread A *pool;
//static void init() {
// pool = new A();
// }
/*static __thread A *instance() {
pool = new A();
return pool;
} */
};
thread_specific_ptr<A> C::pool;
//__thread A *C::pool;
#endif
// list.h
#ifndef __LIST_H
#define __LIST_H
#include "c.h"
class list
{
public:
int start;
int step;
list(int s,int t):start(s), step(t){
//C::init();
C::pool.reset(new A);
C::pool->i = s;
}
void inc() {
C::pool->i += step;
}
int get() {
return C::pool->i;
}
};
#endif
g++ main.cpp -I~/boost -lboost_thread -lpthread -o test
1086380352: 1
1117477184: 1001
1086380352: 2
1117477184: 1006
1086380352: 3
1117477184: 1011
1086380352: 4
1117477184: 1016
1086380352: 5
1117477184: 1021
1086380352: 6
1117477184: 1026
1086380352: 7
1117477184: 1031
1086380352: 8
1117477184: 1036
1086380352: 9
1117477184: 1041
1086380352: 10
1117477184: 1046
http://www.searchtb.com/2012/09/tls.html
此博客也介绍了线程局部变量的对比,至于__thread容易造成内存泄露,不是很明白