C/C++ 线程本地存储
时间:2021-07-13
本文章向大家介绍C/C++ 线程本地存储,主要包括C/C++ 线程本地存储使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
Thread Local Storage
我们知道多线程共享同一个进程的地址空间,对全局变量来说,某一个线程对其修改会影响其他所有线程。
如果我们需要一个变量在每个线程中都能访问,并且值在每个线程中互不影响,这就是 Thread Local Storage(TLS,也称 “线程私有数据”)。
Linux下支持两种方式定义和使用TLS变量,具体如下表:
定义方式 | 支持层次 | 访问方式 |
__thread 关键字 | 语言层面 | 与全局变量完全一样 |
pthread_key_create() 函数 | 运行库层面 |
pthread_get_specific(),读 pthread_set_specific(),写 |
__thread 关键字
看个例子,全局变量 var 被定义为 线程私有变量
#include <stdio.h> #include <stdint.h> #include <pthread.h> __thread int var = 0; // var定义为线程变量,每个数线拥有一份 void* worker(void* arg) { for (int i = 0; i < 1e4; i++) { var++; } printf("child thread [%lu] var(%p)=%d\n", pthread_self(), &var, var); return 0; } int main(){ pthread_t pid1, pid2; printf("var=%d\n", var); pthread_create(&pid1, NULL, worker, (void *)0); pthread_create(&pid2, NULL, worker, (void *)1); pthread_join(pid1, NULL); pthread_join(pid2, NULL); printf("main thread [%lu] var(%p)=%d\n", pthread_self(), &var, var); return 0; }
运行结果
var=0 child thread [139770628466432] var(0x7f1ee2a8e6fc)=10000 child thread [139770620073728] var(0x7f1ee228d6fc)=10000 main thread [139770645350272] var(0x7f1ee3aa877c)=0
可见,主线程和两个子线程访问到的 var 变量地址不一样,每个线程对 var 都有一份自己的拷贝,不会互相影响。
pthread_key_create() 函数
也看个例子,
#include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <pthread.h> struct foo { int var; }; void* worker(void* arg) { pthread_key_t* key = (pthread_key_t*) arg; foo* ptr; if ((ptr = (foo*)pthread_getspecific(*key)) == NULL) { ptr = (foo*) malloc(sizeof(foo)); (void) pthread_setspecific(*key, ptr); } for (int i = 0; i < 1e4; i++) { ptr->var++; } printf("child thread [%lu] var(%p)=%d\n", pthread_self(), &(ptr->var), ptr->var); return 0; } int main(){ pthread_key_t key; (void) pthread_key_create(&key, NULL); pthread_t pid1, pid2; pthread_create(&pid1, NULL, worker, (void *)(&key)); pthread_create(&pid2, NULL, worker, (void *)(&key)); pthread_join(pid1, NULL); pthread_join(pid2, NULL); foo* ptr; if ((ptr = (foo*)pthread_getspecific(key)) == NULL) { printf("main thread [%lu] var null\n"); } else { printf("main thread [%lu] var(%p)=%d\n", pthread_self(), &(ptr->var), ptr->var); } pthread_key_delete(key); return 0; }
运行结果
child thread [140470755546880] var(0x7fc1e00008c0)=10000 child thread [140470747154176] var(0x7fc1d80008c0)=10000 main thread [140470770246240] var null
不同线程通过同一个key,访问到不同的value,可以想象 Linux 的实现会是一个map,每个线程对应不同的value。
======专注高性能web服务器架构和开发=====
原文地址:https://www.cnblogs.com/chenny7/p/15006904.html
- HDUOJ----A Computer Graphics Problem
- HDUOJ---(4708)Herding
- HDUOJ---(4708)Rotation Lock Puzzle
- HDUOJ---Hamming Distance(4712)
- HDUOJ-----Difference Between Primes
- HDUOJ----(4706)Children's Day
- poj-------Common Subsequence(poj 1458)
- poj----Maximum sum(poj 2479)
- HDUOJ---hello Kiki
- HDUOJ-----X问题
- POJ-----C Looooops
- POJ--Strange Way to Express Integers
- HDUOJ----More is better(并查集)
- HDUOJ 1099——Lottery
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Android下Activity间通信序列化过程中的深浅拷贝浅析
- Android升级支持库版本遇到的两个问题详解
- Android开发使用Drawable绘制圆角与圆形图案功能示例
- Android开发中自定义ProgressBar控件的方法示例
- Android 使用自定义RecyclerView控件实现Gallery效果
- Android开发中GridView用法示例
- React Native中Android物理back键按两次返回键即退出应用
- Android仿简书搜索框效果的示例代码
- Android 自定义 HorizontalScrollView 打造多图片OOM 的横向滑动效果(实例代码)
- Android开发自定义TextView省略号样式的方法
- Android开发中获取View视图宽与高的常用方法小结
- Android判断字符串中是否含字母、中文或数字
- 利用Kotlin开发你的第一个Android应用
- Android Picasso使用高斯模糊处理的示例代码
- Android RecyclerView打造悬浮效果的实现代码