有时会需要这种模式,一个全局变量,需要在程序的任何地方都可以使用它,但是当这个变量出现在不同线程时,就要求系统将这个变量拷贝到各个线程中,这样的话,每个线程内部也可以随时访问本线程的全局变量,但是线程之间的这个变量没有任何关系。这样就避免了锁,会提高程序运行的效率。在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;
}

g++ -lpthread  main.cpp -o test

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容易造成内存泄露,不是很明白

thread local storage相关推荐

  1. TLS(Thread Local Storage)问题demo

      C++11中的thread_local是C++存储期的一种,属于线程存储期.存储期定义C++程序中变量/函数的范围(可见性)和生命周期.C++程序中可用的存储期包括auto.register.st ...

  2. java线程本地存储_[并发并行]_[C/C++]_[使用线程本地存储Thread Local Storage(TLS)-win32和pthread比较]...

    场景: 1.  需要统计某个线程的对象上创建的个数. 2. 当创建的堆空间需要根据线程需要创建和结束时销毁时. 3. 因为范围是线程只能看到自己的存储数据,所以不需要临界区或互斥量来维护自己的堆内存. ...

  3. Goroutine Local Storage的一些实现方案和必要性讨论

    Java的ThreadLocal是Java为每个线程提供的专用存储,把一些信息放在ThreadLocal上,可以用于来简化上层应用的API使用.一个显著的应用场景是,有了ThreadLocal后,就不 ...

  4. SAP Spartacus 如何使用 API 从浏览器 local Storage 读取数据

    如下图所示,SAP 电商云 UI,用户的购物车 ID,持久化在浏览器的 local storage 里: 运行时,通过封装好的函数 getStorage 读取: 为什么会触发 State module ...

  5. 使用浏览器的 Local Storage 真的安全吗?

    LocalStorage 是一个 HTML5 网络存储对象,用于将数据存储在客户端--即本地,在用户的计算机上. 本地存储的数据没有到期日期,并且会一直存在,直到被删除. (相比之下,会话存储是另一个 ...

  6. SAP Spartacus 用户登录成功后,Access Token 持久化到浏览器 local storage 的执行原理

    下图第1487行代码,调用Angular HTTP library,往this.tokenEndpoint指向的API发送HTTP post请求,参数为用户在login form里输入的用户名和密码: ...

  7. SAP Spartacus 在未登录状态下浏览器 local storage 里存储的数据

    url: http://localhost:4200/powertools-spa/en/USD/ 未登录状态下: 观察local storage存储的数据: auth: {token: {}, us ...

  8. SAP UI5 应用的调试标志位的本地存储逻辑 - local storage 使用的一个例子

    We know that once we enable debug mode via "Ctrl+Alt+Shift+P", this setting will be persis ...

  9. 关于HTML5本地持久化存储的Web SQL、Local Storage、Cookies技术

    在浏览器客户端记录一些信息,有三种常用的Web数据持久化存储的方式,分别是Web SQL.Local Storage.Cookies. Web SQL 作为html5本地数据库,可通过一套API来操纵 ...

最新文章

  1. LTE CRS 时频资源
  2. JAVA-Socket通信笔记
  3. TCP 滑动窗口简述
  4. Apache Kafka(二)- Kakfa 安装与启动
  5. 34、JS/AJAX
  6. C#实现Combobox自动匹配字符
  7. 2011年计算机一级考试题,2011年计算机一级考试试题及答案
  8. IDEA—使用插件反编译jar包
  9. laravel邮件服务
  10. Java 图片处理解决方案:ImageMagick 快速入门教程
  11. linux6.5输错密码锁定,干货分享:解决redhat6.5登陆后跳回Login,循环登陆问题
  12. 一些收藏默认网站后缀
  13. Github上最热门的Java开源项目
  14. linux系统外接硬盘挂载
  15. sqlserver和mysql定时同步_通过作业,定时同步两个数据库_sqlserver
  16. Android下红包雨的实现
  17. hdu 1116 并查集和欧拉路径
  18. cancase lin管脚_Vector CANCASE XL+CABLE 模块
  19. OpenGL 纹理过滤和 mip 贴图
  20. [读书笔记]结绳记事

热门文章

  1. mysql 语句_如何记录MySQL执行过的SQL语句
  2. 深度学习和目标检测系列教程 18-300:关于yolo、voc格式标签转化问题
  3. 完整的Ubuntu18.04深度学习GPU环境配置,英伟达显卡驱动安装、cuda9.0安装、cudnn的安装、anaconda安装
  4. 一阶暂态电路三要素法和三种响应
  5. tornado函数和类的导入和ui_modules  , ui_methods
  6. 我们可以无损放大一个Transformer模型吗?
  7. web公选课第三节2020.5.18
  8. 点在多边形内外的判断【计算几何】
  9. 逛街 最短距离+花费
  10. Spring框架设计