Linux线程私有数据

[size=medium]
线程私有数据的使用场景是:某个函数在第一次被调用的时候,分配内存block,在以后每次调用的时候,都是用第一次所分配的内存block,无需再次分配。可以用线程私有数据来存储这个内存block。
在多线程环境下,如果不使用线程私有数据,由于函数只分配了一个block,所以各个线程在block上必然会有竞争。如果每个线程对这个block的使用是相互独立的,比如对errno的设置,就可以使用线程私有变量来避免竞争。
可以把线程私有变量看成是一种<key, value>类型的数据结构,对于同一个key,不同的线程可以有不同的value。Linux为这种数据结构提供了GET和SET接口,即:[/size]

void *pthread_getspecific(pthread_key_t key);//获取key所对应的线程私有数据
​int pthread_setspecific(pthread_key_t key, const void *value); //设置key所对应的线程私有数据

[size=medium]
一般而言,比如key是全局变量,需要通过pthread_key_create(&key, destructor)初始化key。线程1调用pthread_setspecific(key, value1);设置了key所对应的值value1。这种设置在另外一个线程2是不可见的,即线程2通过pthread_getspecific(key)是获取不到value1的。同样线程2通过pthread_setspecific(key, value2)对线程1也没有任何影响。

总的来说,就是对于同一个pthread_key,每个线程都对value有一个独立的副本,所以避免了竞争。
具体例子如下,例子来源于《The Linux Programming Interface - A Linux and UNIX System Programming Handbook》:[/size]

#include <stdio.h>
#include <string.h> /* Get declaration of strerror() */
#include <pthread.h>

static pthread_once_t once = PTHREAD_ONCE_INIT;
static pthread_key_t strerrorKey;
#define MAX_ERROR_LEN 256 /* Maximum length of string in per-thread
buffer returned by strerror() */

/* Free thread-specific data buffer */
static void destructor(void *buf) {
free(buf);
}

/* One-time key creation function */
static void createKey(void) {
int s;
/* Allocate a unique thread-specific data key and save the address
of the destructor for thread-specific data buffers */
e s = pthread_key_create(&strerrorKey, destructor);
if (s != 0)
errExitEN(s, "pthread_key_create");
}

char * strerror(int err) {
int s;
char *buf;
/* Make first caller allocate key for thread-specific data */
r s = pthread_once(&once, createKey);
if (s != 0)
errExitEN(s, "pthread_once");
t buf = pthread_getspecific(strerrorKey);
if (buf == NULL) { /* If first call from this thread, allocate
buffer for thread, and save its location */
y buf = malloc(MAX_ERROR_LEN);
if (buf == NULL)
errExit("malloc");
u s = pthread_setspecific(strerrorKey, buf);
if (s != 0)
errExitEN(s, "pthread_setspecific");
}
if (err < 0 || err >= _sys_nerr || _sys_errlist[err] == NULL) {
snprintf(buf, MAX_ERROR_LEN, "Unknown error %d", err);
} else {
strncpy(buf, _sys_errlist[err], MAX_ERROR_LEN - 1);
buf[MAX_ERROR_LEN - 1] = '\0'; /* Ensure null termination */
}
return buf;
}

[size=medium]
thread local和线程私有数据在概念上差不多,thread local为线程私有数据提供了更方便的访问接口。
如下例子[/size]
static __thread char local_buf[MAX_ERROR_LEN];

[size=medium]
定义static变量local_buf,通过__thread修饰,则每个线程都对local_buf,都会有一个独立的副本,它们自己不会相互干扰
通过如下程序的输出,我们可以看到,不同的线程local_buf的地址是不同的,所以每个线程可以独立的对buf修改。[/size]


#include <stdio.h>
#include <string.h>
#include <pthread.h>

#define MAX_ERROR_LEN 10240

static char normal_buf[MAX_ERROR_LEN];
static __thread char local_buf[MAX_ERROR_LEN];

void * func(void * arg) {
printf("thread %x : local_buf %x\n", pthread_self(), local_buf);
printf("thread %x : normal_buf %x\n", pthread_self(), normal_buf);
}

int main() {

pthread_t tid;
pthread_create(&tid, NULL, func, NULL);

func(NULL);
pthread_join(tid, NULL);
return 0;
}
基于单片机的继电器参数测试系统设计 由于原有测试系统在参数设置上过于单一,在对继电器测试过程中需要多次进行器件连接,导致对其测试准确度下降,会造成继电器的二次损伤,基于单片机研究继电器参数测试系统的设计方法。在硬件设计上,构建二级模式集散控制框架,利用单片机进行数据采集和处理,满足实时继电器参数数据的同步控制;设计双极性反向比例输出电路,分别利用电极电阻对继电器两侧电压进行放大,实现继电器实时电压的检测。实验结果:以两组类型断电器为测试对象,分别连接示波器进行真实数据采集,在本文系统的应用下所得参数测试结果,与真实的数据相一致,具有实际应用效 阅读详情

相关推荐

VisionMaster SDK C#二次开发核心技术指南

以下是基于**VisionMaster SDK C#二次开发核心技术指南**,结合实战案例与关键代码解析,帮助开发者快速掌握工业视觉应用集成。

东城十三 3057

Linux系统编程(线程私有数据)

在多线程程序中,经常要用全局变量来实现多个函数间的数据共享。由于数据空间是共享的,因此全局变量也为所有线程共有。 测试代码如下: #include &lt;stdio.h&gt; #include &lt;pthread.h&gt; #include &lt;unistd.h&gt; #include &lt;stdlib.h&gt; int key = 100; //全局变量 void...

小麦大大博客 490

基于PSINS的INS/NHC/ODO组合导航仿真全解析

组合导航通过多传感器融合克服单一导航系统的局限,是车辆自主定位的关键技术。其中惯性导航(INS)依靠陀螺仪与加速度计积分推算运动状态,但误差随时间累积;GNSS提供绝对位置,却在城市峡谷中易受多径效应和遮挡影响导致定位漂移。卡尔曼滤波作为信息融合核心,将不同量测按统计特性加权,实现优势互补。基于PSINS开源工具箱搭建的SINS/GNSS/ODO/NHC组合导航仿真,能够在GNSS失锁条件下利用非完整约束和里程计抑制惯性误差发散,广泛应用于无人驾驶、物流车辆自主定位等场景。本文围绕PSINS仿真环境,详细拆

weixin_29044713的博客 253

linux线程私有数据详解

在单线程程序中,函数经常使用全局变量或静态变量,这是不会影响程序的正确性的,但如果线程调用的函数使用全局变量或静态变量,则很可能引起编程错误,因为这些函数使用的全局变量和静态变量无法为不同的线程保存各自的值,而当同一进程内的不同线程几乎同时调用这样的函数时就可能会有问题发生。而解决这一问题的一种方式就是使用线程私有数据。线程私有数据采用了一种被称为一键多值的技术,即一个键对应多个数值。访问数据时都

caoyan_12727的博客 6975

CST微波工作室端口设置保姆级教程:从波导端口到离散端口,手把手教你搞定S参数仿真

本文提供CST微波工作室端口设置的详细教程,涵盖波导端口和离散端口的选择与配置,助力工程师精准完成S参数仿真。通过微带线滤波器案例,详解端口尺寸、阻抗设置及常见问题排查,提升仿真效率与准确性。

weixin_42570296的博客 362

使用 Python 实现无人机避障的人工势场算法

人工势场算法是一种基于力的控制方法,通过将目标位置视为一个吸引力源,而将障碍物视为排斥力源,来引导移动体朝着目标前进,同时避开障碍物。接下来,我们将定义几个类来实现人工势场算法,包括无人机类、障碍物类和势场类。

闲人编程的博客 2585

linux下线程私有数据实现原理及使用方法总结

私有数据使用 1.为什么需要线程私有数据: 原因一:有时候需要维护基于每个线程的数据,用线程ID作为索引。因为线程ID不能保证是小而连续的整数,所以不能简单的分配一个线程数据数组,用线程ID作为数组的索引。即使线程ID确实是小而连续的整数,可能还希望有一些额外的保护,以防止某个线程的数据和其它线程的数据相混淆。 原因二:可以让基于进程的接口适应多线程环境,比如errno,线程出现以前errn

lvfengchang1220的专栏 592

自动驾驶IDM与MOBIL模型

IDM模型,自动驾驶

不想学好数学的汽车工程师不是一个好的程序员 1万+

linux线程私有数据

今天在看线程的私有数据时,一直想找个例子,实际的验证下,用数据告诉自己:"对,就是那样的,那就是TSD“,于是乎我看到了这个例子 http://www.ibm.com/developerworks/cn/linux/thread/posix_threadapi/part2/,不得不说IBMdeveloperworkshop这的很好,有很多非常优秀的文章,至于原创与否我没有考证,不下结论,于是乎下

写代码的小孩 2365

DCDC电路断电时放电波形发生震荡和电压跳变问题,如何解决?

DCDC电路断电时放电波形发生震荡和电压跳变问题: 做的一个项目需要用单片机ADC采集电压,要让单片机感应到电压降到3.1V开始往FLASH里存数据,单片机2.4V基本上就工作不了,(根据单片机手册的,擦写的时间在40mS在左右)所以3.1V降到2.4V的时间必须要大于40mS岁以上,在单片机VCC处加了一个100nF的电容,理论仿真下来150mS左右发现存不进去,用示波器抓了一下波形,发现放电时震荡很严重,实际3.1V到2.4V时间只有10ms左右,这个肯定存不进去; 请教师傅说是应该时前级DCDC开关电

**My Coding Family** 1968

Python 爬虫实战:手机应用商店评论数据爬取与分析

移动应用市场蓬勃发展,用户的评论数据包含了大量有价值的信息,如用户满意度、功能反馈、改进建议等。通过分析这些评论,我们可以挖掘应用的优缺点,甚至预测用户趋势。由于 Apple App Store 评论是动态加载的,我们使用。本篇博客将详细介绍如何使用 Python 爬取。爬取大量数据时,可能会遇到反爬机制。库获取 Google Play 评论。评论数据是动态加载的,需要使用。

2201_76125261的博客 2323

linux 多线程应用--线程内部私有的全局变量

在 单线程的程序里,有两种基本的数据:全局变量和局部变量。但在多线程程序里,还 有第三种数据类型:线程数据(TSD: Thread-Specific Data)。它和全局变量很象,在线程 内部,各个函数可以象使用全局变量一样调用它,但它对线程外部的其它线程是不可见 的。这种数据的必要性是显而易见 的。例如我们常见的变量 errno,它返回标准的出错信 息。 它显然不能是一个局部变量,几乎

code 3379

YOLOv8集成CPCA(Combined Parallel Convolutional Attention)注意力机制模块YOLOv8深度教程

YOLOv8集成CPCA注意力模块教程摘要 本教程详细介绍了如何将YOLOv8 CPCA(Combined Parallel Convolutional Attention)注意力模块集成到YOLOv8目标检测框架中。CPCA模块结合了通道注意力和多尺度空间注意力机制,通过全局池化和双路径融合增强通道特征,并利用多尺度深度可分离卷积捕获空间上下文信息。YOLOv8 教程包含完整的实现步骤:创建CPCA模块代码、修改YOLOv8模型解析逻辑、编写自定义配置文件,YOLOv8YOLOv8YOLOv8YOLOv8

FJN110的博客 1620

Linux系统编程——线程概述、线程控制和线程私有数据

在许多经典的操作系统教科书中,总是把进程定义为程序的执行实例,它并不执行什么, 只是维护应用程序所需的各种资源,而线程则是真正的执行实体。在一个进程中的多个执行路线叫做线程。为了让进程完成一定的工作,进程必须至少包含一个线程。线程又叫轻量级进程(LWP)。线程会共享进程的一些资源,也有一些资源是线程独立拥有的。但是不同进程的线程是不共享资源的。【共享】:代码区、数据区、堆区(注意没有栈区)、环境变量和命令行参数、文件描述符、信号处理函数、当前目录、用户 ID 和组 ID 等。

qq_74811378的博客 1468

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

Linux线程私有数据Thread-specific Data(TSD) 详解

Linux线程私有数据Thread-specific Data(TSD) 详解。本文将详细介绍pthread_key的用法以及pthread_key的原理。pthread_key在《ntyco协程》中,以及后续文章《try catch的实现》都有用到。跟我一起学习的读者务必搞懂原理。......

清风 4495

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

linux c线程控制—私有数据和线程同步

线程这一章,着实不好理解,写上一篇博客时,我还没这么想, 今天做了几道关于线程的题,觉得还是不行呀,还是乖乖再来一遍吧。 私有数据: 线程同步 条件变量 异步信号 1、私有数据 为什么要有线程私有数据呢? 我们知道在多线程环境下,进程内的所有线程共享进程的数据空间,所以全局变量为所有线程共有,但是在程序设计的时候有时需要保存线程自己的全局变量,例如:变量errno:返回标...

tiandc的博客 635

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

linux 线程私有数据

类似于errno,不是全局变量,因为多个线程同时访问的话可能出现资源同步问题,私有数据是一键对多值,每个线程可以根据同一个key,设置自己的数据,也可以通过key对数据进行获取 #include <stdio.h> #include <stdlib.h> #include <pthread.h> pthread_key_t key; struct stud...

CodeHouse的博客 354

Linux多线程基础学习(八)私有数据

在进程内的所有线程共享相同的地址空间,任何声明为静态或外部的变量,或在进程堆声明的变量,都可以被进程所有的线程读写。那怎样才能使线程序拥有自己的私有数据呢。 posix提供了一种方法,创建线程键。 1.为什么需要线程私有数据:       原因一:有时候需要维护基于每个线程的数据,用线程ID作为索引。因为线程ID不能保证是小而连续的整数,所以不能简单的分配一个线程数据数组,用线程ID作为数组

Ryan Smith的专栏 1182

linux 线程私有数据之一键多值技术TSD池

linux 线程私有数据之 一键多值技术 进程内的所有线程共享进程的数据空间,因此全局变量为所有线程所共有。但有时线程也需要保存自己的私有数据,这时可以创建线程私有数据(Thread- specific Date)TSD来解决。在线程内部,私有数据可以被各个函数访问,但对  linux 线程私有数据之 一键多值技术 进程内的所有线程共享进程的数据空间,因此全局变量为所有线程所共有。但有

晴天的专栏 2698

多线程4——线程私有数据(linux)

多线程4——线程私有数据(linux)

Jerry的博客 367

c 语言线程私有变量,linux下C语言多线程(二)线程的私有数据

一. 概念及作用在单线程程序中,我们经常要用到"全局变量"以实现多个函数间共享数据。在多线程环境下,由于数据空间是共享的,因此全局变量也为所有线程所共有。现在有一全局变量,所有线程都可以使用它,改变它的值。而如果每个线程希望能单独拥有它,那么就需要使用线程存储了。表面上看起来这是一个全局变量,所有线程都可以使用它,而它的值在每一个线程中又是单独存储的。这就是线程存储的意义。这样的数据结构可以由Po...

weixin_35033082的博客 1115

Linux--线程的私有数据如何创建销毁和读取

Linux--线程的私有数据如何创建销毁和读取线程的私有数据私有数据的创建销毁以及读取私有数据的定义pthread_key_create参数:int pthread_key_delete参数:void *pthread_getspecific参数pthread_setspecific参数:demo运行效果 线程的私有数据 我们知道,Linux中多线程之间是共享内存的,那么一个全局变量更改了会影响别的线程,那么如何定义线程自己的私有数据呢? TSD私有数据,同名但是不同内存地址的私有数据结构 私有数据的创建销

一只青木呀 563

ZT linux 线程私有数据之 一键多值技术

这个原作者的这个地方写错了 且他举的例子非常不好。最后有我的修正版本 pthread_setspecific(key, (void *)&my_errno); linux 线程私有数据之一键多值技术TSD池 2012-09-15 16:22:08 分类: LINUX linux 线程私有数据之 一键多值技术 ...

weixin_30542079的博客 104

linux线程私有数据的保护

来自于:http://www.cppblog.com/prayer/archive/2009/07/05/89286.html   linux下的线程真是很有趣,各种在windows编程里看不到的技巧在这里尽显无余。在一个进程里有许多的线程,这些线程共享进程里的所有资源。包括数据空间,所以全局变量是为所有的线程所共享的。但如果线程里的全局变量为所有的线程所共享会出现一些问题。比如如果代码量很大

lieye_leaves的专栏 764

Linux学习笔记:线程私有数据

在学习线程操作的过程中,我一直对线程私有数据的作用很困惑,不知道它到底有什么作用,但经过一段时间的探索后,我总结了一部分关于线程私有数据的用法,如果有不对或者不够详细的地方,请指出。 线程私有数据的实现: 线程的私有数据采用了一种被称为 "一键多值" 的技术,即一个键对应多个数值。 操作线程私有数据的函数主要有4个: 1> pthread_key_create();

436

linux学习之十五---多线程私有数据

linux多线程 私有数据 在多线程环境下,进程内的所有线程共享进程的数据空间,因此全局变量为所有线程共有。在程序设计中有时需要保存线程自己的全局变量,这种特殊的变量仅在某个线程内部有效。 线程私有数据采用立一种被称为一键多值的技术,即一个键对应多个数值。访问数据都是通过键值来访问,好像是对一个变量进行访问,其实是在访问不同的数据。使用线程私有数据时,首先要为每个线程数据创建一个相关联的键。在

lanzh_ 931
上一篇: 使用Tornado和Redis构建简易聊天室
「已注销」
博客等级 码龄16年 1粉丝 84原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值