下面说一下线程中特有的线程存储, Thread Specific Data 。线程存储有什么用了?他是什么意思了?大家都知道,在多线程程序中,所有线程共享程序中的变量。现在有一全局变量,所有线程都可以使用它,改变它的值。而如果每个线程希望能单独拥有它,那么就需要使用线程存储了。表面上看起来这是一个全局变量,所有线程都可以使用它,而它的值在每一个线程中又是单独存储的。这就是线程存储的意义。
下面说一下线程存储的具体用法。
l 创建一个类型为 pthread_key_t 类型的变量。
l 调用 pthread_key_create() 来创建该变量。该函数有两个参数,第一个参数就是上面声明的 pthread_key_t 变量,第二个参数是一个清理函数,用来在线程释放该线程存储的时候被调用。该函数指针可以设成 NULL ,这样系统将调用默认的清理函数。
l 当线程中需要存储特殊值的时候,可以调用 pthread_setspcific() 。该函数有两个参数,第一个为前面声明的 pthread_key_t 变量,第二个为 void* 变量,这样你可以存储任何类型的值。
l 如果需要取出所存储的值,调用 pthread_getspecific() 。该函数的参数为前面提到的 pthread_key_t 变量,该函数返回 void * 类型的值。
下面是前面提到的函数的原型:
int pthread_setspecific(pthread_key_t key, const void *value);
void *pthread_getspecific(pthread_key_t key);
int pthread_key_create(pthread_key_t *key, void (*destructor)(void*));
下面是一个如何使用线程存储的例子:
#include <malloc.h>
#include <pthread.h>
#include <stdio.h>
/* The key used to associate a log file pointer with each thread. */
static pthread_key_t thread_log_key;
/* Write MESSAGE to the log file for the current thread. */
void write_to_thread_log (const char* message)
{
FILE* thread_log = (FILE*) pthread_getspecific (thread_log_key);
fprintf (thread_log, “%s\n”, message);
}
/* Close the log file pointer THREAD_LOG. */
void close_thread_log (void* thread_log)
{
fclose ((FILE*) thread_log);
}
void* thread_function (void* args)
{
char thread_log_filename[20];
FILE* thread_log;
/* Generate the filename for this thread’s log file. */
sprintf (thread_log_filename, “thread%d.log”, (int) pthread_self ());
/* Open the log file. */
thread_log = fopen (thread_log_filename, “w”);
/* Store the file pointer in thread-specific data under thread_log_key. */
pthread_setspecific (thread_log_key, thread_log);
write_to_thread_log (“Thread starting.”);
/* Do work here... */
return NULL;
}
int main ()
{
int i;
pthread_t threads[5];
/* Create a key to associate thread log file pointers in
thread-specific data. Use close_thread_log to clean up the file
pointers. */
pthread_key_create (&thread_log_key, close_thread_log);
/* Create threads to do the work. */
for (i = 0; i < 5; ++i)
pthread_create (&(threads[i]), NULL, thread_function, NULL);
/* Wait for all threads to finish. */
for (i = 0; i < 5; ++i)
pthread_join (threads[i], NULL);
return 0;
}
最后说一下线程的本质。
其实在Linux 中,新建的线程并不是在原先的进程中,而是系统通过一个系统调用clone() 。该系统copy 了一个和原先进程完全一样的进程,并在这个进程中执行线程函数。不过这个copy 过程和fork 不一样。copy 后的进程和原先的进程共享了所有的变量,运行环境。这样,原先进程中的变量变动在copy 后的进程中便能体现出来。
相关推荐
OPC UA 服务端的模拟工具及客户端工具
详细介绍如何使用 Prosys OPC UA Simulation Server 作为 OPC UA 服务端的模拟工具来生成数据模型,并使用 Softing OPC UA Client 作为客户端工具,直观地查看和验证模拟生成的数据。
Linux多线程之pthread_key_create()
本文介绍了pthread_key_create()函数在多线程编程中的基本概念、功能和使用方法。通过了解pthread_key_create()的使用,可以更好地管理多线程编程中的线程特定数据,避免数据竞争和其他相关问题的发生。在使用pthread_key_create()函数时,需要注意以下几点:1 键的范围pthread_key_t类型的键的范围通常是有限的,具体取决于系统的实现。因此,在创建和使用键时,应确保键的数量不会超出系统限制。2 线程特定数据的初始化。
抖音短连接v.douyin.com/xxx 如何生成?
最近公司有个需求,在抖音里如何宣传自己的网站,并且不要有拦截域名的提示,截图如下。 通过ida反编译抖音的app后,将下载后的ipa文件用解压缩软件(如7zip等)解压,从解压后的目录Payload/Aweme.app/找到Aweme可执行文件,拖入ida进行反编译,ida可以检测objective-c语法。 然后进入主题,既然是聊天发消息,就尝试在ida里搜索"message",看看能否找到对...
pthread_key_t和pthread_key_create()详解
现在有一全局变量,所有线程都可以使用它,改变它的值。表面上看起来这是一个全局变量,所有线程都可以使用它,而它的值在每一个线程中又是单独存储的。这就是线程存储的意义。该函数有两个参数,第一个参数就是上面声明的pthread_key_t变量,第二个参数是一个清理函数,用来在线程释放该线程存储的时候被调用。该函数有两个参数,第一个为前面声明的pthread_key_t变量,第二个为void*变量,这样你可以存储任何类型的值。该函数的参数为前面提到的pthread_key_t变量,该函数返回void *类型的值。
MaPLe: Multi-modal Prompt Learning
具体而言,我们在语言分支中附加可学习的上下文标记,并通过耦合函数显式地将视觉 Prompt 置于语言 Prompt 上,以建立它们之间的交互。使用 Prompt 来适应CLIP (语言或视觉) 的单个分支中的表示是次优的,因为它不允许在下游任务上动态调整两个表示空间的灵活性。由此,提出了一种分支感知的多模态 Prompt,通过在两种模态之间共享提示来协调 CLIP 的视觉和语言分支。在 Prompt Tuning 中,必须采取多模态方法获得同时适应 CLIP 的视觉和语言分支,以实现上下文优化的完整性。
【顾邦小讲堂】第二十四期 电源环路测试从入门到精髓:一文掌握环路测试原理与电压注入点选择依据
电源环路测试是评估开关电源、线性电源等闭环系统稳定性的核心手段,直接关系到电源的稳定性、输出精度、动态响应、抗干扰能力甚至可靠性
pthread_key_create函数
函数原型: int pthread_key_create(pthread_key_t *key, void(*destructor)(void*)); 功能: 分配用于表示进程中线程特定数据的键,键对进程中的所有线程来说是全局的。创建线程特定数据时,所有线程最初 都具有与该键关联的NULL值。POSIX要求系统至少支持128TSD 头文件:#include pthread非linux
告别Modern Standby噩梦:Win11睡眠断网冻结的根源剖析与S3睡眠回归实战
本文深入剖析了Windows 11中Modern Standby(现代待机)模式导致睡眠后断网、系统冻结等问题的根源,指出其与硬件驱动、后台活动的兼容性矛盾。文章提供了通过修改注册表键值强制系统回归稳定S3睡眠状态的详细实战步骤,帮助用户彻底解决睡眠故障,实现可靠的远程访问与挂机任务。
Linux多线程学习(三)pthread_key_create
函数 pthread_key_create() 用来创建线程私有数据。该函数从 TSD 池中分配一项,将其地址值赋给 key 供以后访问使用。第 2 个参数是一个销毁函数,它是可选的,可以为 NULL,为 NULL 时,则系统调用默认的销毁函数进行相关的数据注销。如果不为空,则在线程退出时(调用 pthread_exit() 函数)时将以 key 锁关联的数据作为参数调用它,以释放分配的缓冲区
一篇关于轴承故障诊断的综述
在设备的故障检测中,有约30%-40%的设备故障是由轴承故障引起的,因此本文将列举有关检测轴承故障使用到的相关数据集,模型和算法。 数据集 现有的数据集,普遍由固定在电机马达上的两个震动检测器获得,并根据需要,分离震动数据在时域和频域上的特征以供网络模型学习。 不同的数据集,区别在于,检测的马达转速不同,环境不同,取样频率不同,一段样本的时长不同等等 (1)Case Western Reserve University (CWRU) Dataset 该数据集拥有多种数据,测量的时候,通过改变轴承.
ZeroClaw安装、使用方法详细全解
ZeroClaw 是一个用 Rust 编写的轻量级、高性能、完全自主的 AI 助手运行时框架
pthread_once、pthread_key_create和pthread_getspecific和pthread_setspecific
NativeMessageQueue::NativeMessageQueue() { mLooper = Looper::getForThread(); if (mLooper == NULL) { mLooper = new Looper(false); Looper::setForThread(mLooper); } } s
sap中途启用物料账
spro->控制->产品成本控制->实际成本核算/物料分类帐->实际成本核算->激活实际成本的在产品。spro->控制->产品成本控制->实际成本核算/物料分类帐->实际成本核算->激活实际成本组件划分。spro->控制->产品成本控制->实际成本核算/物料分类帐->实际成本核算->激活实际成本核算。spro->控制->产品成本控制->实际成本核算/物料分类帐->激活评估范围的物料分类账。2.对于之前存在物料移动,但是期初没有库存的物料,物料分类账里追踪不到相关物料信息。1.需要激活物料分类账。
一句话讲明白 pthread_key_t和pthread_key_create()
pthread_key_t和pthread_key_create()
C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片
基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正
jdk-8u144-linux-x64.tar.gz.
该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包
线程存储pthread_key_create
下面说一下线程中特有的线程存储, Thread Specific Data 。 线程存储有什么用了?他是什么意义?大家都知道,在多线程程序中,所有线程共享程序中的变量。 现在有一全局变量,所有线程都可以使用它,改变它的值。而如果每个线程希望能单独拥有它,那么就需要使用线程存储了。 表面上看起来这是一个全局变量,所有线程都可以使用它,而它的值在每一个线程中又是单独存储的。这就是线程存储的意义。
Statistics and Machine Learning Toolbox
Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具
关于线程的私有存储pthread_key_t
最近在工作中遇到了线程的私有存储的东东,现将对pthre...
Probability and Statistics - 4th edition
Probability and Statistics - 4th edition
9857



被折叠的 条评论
为什么被折叠?



