《Linux C编程实战》笔记:线程私有数据

在多线程环境下,进程内的所有线程共享进程的数据空间,因此全局变量为所有线程共有。在程序设计中有时需要保存线程自己的全局变量,这种特殊的变量仅在某个线程内部有效。如常见的变量errno,它返回标准的出错代码。errno不应该是一个局部变量,几乎每个函数都应该可以访问它;但它又不能作为是一个全局变量,否则在一个线程 里输出的很可能是另一个线程的出错信息,这个问题可以通过创建线程的私有数据(Thread-specific Data,或TSD)来解决。
在线程内部,线程私有数据可以被各个函数访问,但它对其他线程是屏蔽的。线程私有数据采用了一种被称为一键多值的技术,即一个键对应多个数值。访问数据时都是通过键值来访问,好像是对一个变量进行访问,其实是在访问不同的数据。使用线程私有数据时,首先要为每个线程数据创建一个相关联的键。在各个线程内部,都使用这个公用的键来指代线程数据,但是在不同的线程中这个键代表的数据是不同的。操作线程私有数据的函数主要有4个:
pthread_key_create (创建一个键), pthread_setspecific(为一个键 设置线程私有数据),pthread_getspecifie(从一个键读取线程私有数据)pthread_key_delete (删除一个键)。 这几个函数的声明如下:

#include <pthread.h>
int pthread_key_create (pthread_key_t *key, void (*destr_ function) (void *));
int pthread_setspecific(pthread_key_t key, const void * pointer);
void* pthread_getspecific (pthread_key_t key);
int pthread_key_delete (pthread_key_t key);
  1. pthread_key_create:

    • 目的:用于创建一个线程特定数据的键。
    • 参数:
      • key:一个指向 pthread_key_t 变量的指针,用于存储键。
      • destr_function:一个指向析构函数的指针,在线程退出时会调用该函数,并以key所关联的数据作为参数。
  2. pthread_setspecific:

    • 目的:用于将线程特定值与键关联起来。
    • 参数:
      • key:之前使用 pthread_key_create 创建的键。
      • pointer:要与当前线程的键关联的数据的指针。
  3. pthread_getspecific:

    • 目的:检索与给定键关联的线程特定值。
    • 参数:
      • key:要检索当前线程的键关联的线程特定值。
    • 返回值:指向与键关联的线程特定数据的指针,用于当前线程。
  4. pthread_key_delete:

    • 目的:用于删除线程特定数据的键。
    • 参数:
      • key:使用 pthread_key_create 创建的要删除的键。
    • 返回值:成功时返回0,如果发生错误则返回错误代码。
    • 删除后,键所占用的内存被释放,与键关联的线程数据所占用的内存并不被释放。所以,要记得先释放线程数据。

可以这么理解,键值是对所有线程都可见的全局变量,但是不同线程可以让同一键值关联到线程自身的数据,从而实现不同线程通过同一全局的键值得到不同数据(通过getspecific获得)。

示例程序

书上示例程序运行起来也是问题重重,我也改了一下

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
pthread_key_t key;
void *thread2(void *arg){int tsd=5;printf("thread %d is running\n",pthread_self());pthread_setspecific(key,(const void *)&tsd);//线程2给key关联到线程2的tsdprintf("thread %d returns %d\n",pthread_self(),*(int *)pthread_getspecific(key));return nullptr;
}
void *thread1(void *arg){int tsd=0;pthread_t thid2;//线程1又创建了一个线程2printf("thread %d is running\n",pthread_self());pthread_setspecific(key,(const void *)&tsd);//这是线程1里面给key关联到线程1的tsdpthread_create(&thid2,nullptr,thread2,nullptr);sleep(5);printf("thread %d returns %d\n",pthread_self(),*(int *)pthread_getspecific(key));return nullptr;
}
int main(){pthread_t thid1;//线程1printf("main thread begins running \n");pthread_key_create(&key,nullptr);//创建键值,没有清理函数所以第二个参数给了nullpthread_create(&thid1,nullptr,thread1,nullptr);sleep(10);pthread_key_delete(key);printf("main thread exit\n");return 0;
}

运行结果如图,可以看到不同的线程对key执行getspecific会得到不同的值

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/337878.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

冬日暖阳行走澳门探寻金沙度假区美食,游行全攻略

澳门金沙度假区是一个集度假、娱乐、购物、美食于一体的综合性旅游胜地。里面光酒店就有7家&#xff08;威尼斯人、巴黎人、四季、瑞吉、康莱德、假日、喜来登&#xff09;&#xff1b;大型购物中心4个&#xff08;四季名店、威尼斯人购物中心、巴黎人购物中心、金沙广场&#…

export default 和exprot

1.默认导入和默认导出 语法: export default {需要输出的内容} 接收: import 成员变量的名字 from 文件夹的路径 案例&#xff1a; a.mjs文件夹下默认导出 export default{a:10,b:20,show(){console.log(123);} } 在b.mjs文件中用成员变量进行接收 import AA from &q…

C语言之三子棋小游戏的应用

文章目录 前言一、前期准备模块化设计 二、框架搭建三、游戏实现打印棋盘代码优化玩家下棋电脑下棋判断输赢 四、结束 前言 三子棋是一种民间传统游戏&#xff0c;又叫九宫棋、圈圈叉叉棋、一条龙、井字棋等。游戏分为双方对战&#xff0c;双方依次在9宫格棋盘上摆放棋子&#…

构建安全可靠的系统:第十六章到第二十章

第四部分&#xff1a;维护系统 原文&#xff1a;Part IV. Maintaining Systems 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 准备应对不舒适情况的组织有更好的机会处理关键事件。 尽管不可能为可能扰乱您组织的每种情况制定计划&#xff0c;但作为综合灾难规划策略…

dubbo的springboot集成

1.什么是dubbo&#xff1f; Apache Dubbo 是一款 RPC 服务开发框架&#xff0c;用于解决微服务架构下的服务治理与通信问题&#xff0c;官方提供了 Java、Golang 等多语言 SDK 实现。使用 Dubbo 开发的微服务原生具备相互之间的远程地址发现与通信能力&#xff0c; 利用 Dubbo …

近两年最火的图像处理算法

近两年&#xff08;2022-2023年间&#xff09;在图像处理领域&#xff0c;有几个算法和技术特别受到关注。这些技术在提高图像质量、加速处理过程以及提升图像识别的准确性方面取得了显著进展。 以下是一些显著的例子&#xff1a; 生成对抗网络&#xff08;GANs&#xff09; GA…

基于sprinmgboot实习管理系统源码和论文

随着信息化时代的到来&#xff0c;管理系统都趋向于智能化、系统化&#xff0c;实习管理也不例外&#xff0c;但目前国内仍都使用人工管理&#xff0c;市场规模越来越大&#xff0c;同时信息量也越来越庞大&#xff0c;人工管理显然已无法应对时代的变化&#xff0c;而实习管理…

基于SELinux三权分立配置方法

1.系统安装 系统安装完成后,系统当前的SELinux配置为: # cat /etc/selinux/config SELINUX=enforcing SELINUXTYPE=targeted 2.SELinux环境准备 # yum install setools policycoreutils.x86_64 selinux-policy-mls.noarch setroubleshoot.x86_64 setools-console -y 3.SELin…

共享经济风潮下的国际化之路:品牌出海的机遇与挑战解析

近年来&#xff0c;共享经济在全球范围内迅速崛起&#xff0c;成为商业模式的新风口。随着这一趋势的发展&#xff0c;许多品牌开始积极出海&#xff0c;将共享理念带到国际市场。共享经济的全球化为品牌提供了前所未有的机遇&#xff0c;然而&#xff0c;也伴随着一系列的挑战…

【昕宝爸爸系列】如何将集合变成线程安全的?

如何将集合变成线程安全的? ✅典型解析&#x1f7e2;拓展知识仓☑️Java中都有哪些线程安全的集合&#xff1f;&#x1f7e0;线程安全集合类的优缺点是什么&#x1f7e1;如何选择合适的线程安全集合类☑️如何解决线程安全集合类并发冲突问题✔️乐观锁实现方式 (具体步骤)。✅…

Vue-9、Vue事件修饰符

1、prevent 阻止默认事件 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>事件修饰符</title><!--引入vue--><script type"text/javascript" src"https://cdn.jsdeliv…

烟火检测AI边缘计算智能分析网关V4在安防项目中的应用及特点

一、行业背景 随着社会和经济的发展&#xff0c;公共安全和私人安全的需求都在不断增长。人们需要更高效、更准确的安防手段来保障生命财产安全&#xff0c;而人工智能技术正好可以提供这种可能性&#xff0c;通过智能监控、人脸识别、行为分析等手段&#xff0c;大大提高了安防…