pthread_key_t和pthread_key_create()详解

2023-05-16

下面说一下线程中特有的线程存储, 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 后的进程中便能体现出来。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

pthread_key_t和pthread_key_create()详解 的相关文章

随机推荐

  • 倡议书:关于暂停「巨型 AI」 实验的一封公开信

    本文是 futureoflife 公开信 xff0c 原文地址 https futureoflife org open letter pause giant ai experiments 目前已经有 1127 1127 1127 名 AI
  • 学习笔记 | Meta AI:分割一切的 SAM 模型

    文章目录 一 前言 二 主要内容 1 惊艳的效果 2 方法介绍 3 未来展望 三 解决方案关键 四 代码实践 五 讨论 一 前言 Meta AI 博客 Introducing Segment Anything Working toward
  • GPT-4 验明真身的三个经典问题:快速区分 GPT-3.5 与 GPT-4

    现在已经有很多 ChatGPT 的套壳网站 xff0c 以下分享验明 GPT 4 真身的三个经典问题 xff0c 帮助你快速区分套壳网站背后到底用的是 GPT 3 5 还是 GPT 4 测试问题 1 xff1a What is tomorr
  • 解决 Microsoft Edge Dev 版本中右上角的 bing 按钮消失的问题 让 New Bing 还能阅读分析文档!

    Microsoft Edge Dev 右上角的必应图标消失了 xff0c 使得无法用 New Bing 阅读分析文档 xff0c 到底什么原因呢 xff1f 针对 Microsoft Edge Dev 版本中右上角的发现按钮消失的问题 xf
  • OpenStack网络指南(7)防火墙即服务(Firewall-as-a-service)

    Firewall as a Service xff08 FWaaS xff09 插件将防火墙应用于OpenStack对象 xff0c 如项目 xff0c 路由器和路由器端口 OpenStack防火墙的核心概念是防火墙策略和防火墙规则的概念
  • OpenStack网络指南(14)DNS集成

    此页面作为如何使用网络服务的DNS集成功能的指南 描述的功能从两个角度涵盖DNS xff1a 网络服务提供的内部DNS功能及其与Compute服务的交互 将计算服务和网络服务与外部DNSaaS xff08 DNS即服务 xff09 集成 用
  • 2022年,立个Flag

    2021年在平静的生活中 xff0c 慢慢的从手指缝中划过 xff0c 新的一年已经都来 xff0c 我也立下几个flag xff0c 待明年末来验收 2022年我希望自己可以开始并坚持做一些事 xff1a 1 实现自己定义的目标 xff0
  • 零开始学习OpenWrt完美教程

    http zhidx com p 186 html 从零开始学习OpenWrt完美教程 Cisco Linksys在2003年发布了WRT54G这款无线路由器 xff0c 同年有人发现它的IOS是基于Linux的 xff0c 然而Linux
  • Sublime Text3使用总结

    写在前面的话 xff1a 平时做项目中在用eclipse和vs xff0c 但是对于一些小项目 xff0c 感觉没有必要搞那么大的一个工具使用 xff0c 比如写个小微商城 xff0c 搞个小脚本了什么 xff0c 所以就一直在用Subli
  • Gym 101028J 100541D

    Gym 100499I 这题当理解题意的时候就出现一个难题 xff0c 循环小数怎么转化为分数 xff0c 果断百度下 普及知识 xff1a 1 纯循环小数 小数点后有几位数 分母就有几个9 分子为一个循环节 如 0 345 345循环 6
  • Wayland与Weston简介

    xfeff xfeff 简单地说 xff0c Wayland是一套display server Wayland compositor 与client间的通信协议 xff0c 而Weston是Wayland compositor的参考实现 其
  • 什么是IaaS,PaaS和SaaS及其区别

    云计算的三种服务模式 xff1a IaaS xff0c PaaS和SaaS Infrastructure xff08 基础设施 xff09 as a Service xff0c Platform xff08 平台 xff09 as a Se
  • Backup for tire

  • 用QXDM获取log的方法说明

    用 QXDM 获取 log 的方法说明 对于获取 LOG 可能我们会有一些误解 测试人员害怕得到的 LOG 信息不全 而将所有的选项都选上 希望能够得到最全的 LOG 其实不然 受到手机及手机与 PC 的通讯限制 如果选择保存所有的 LOG
  • Python环境变量PYTHONPATH设置和easy_install简单使用

    1 把自己编写的 python模块添加到 PYTHONPATH上 要想让 python解释器找到自己编写的模块 xff0c 则该模块必须 PYTHONPATH上 xff0c 否则在导入该模块时会出现找不到该模块的错误 xff0c 因此必须把
  • 超级有用的git reset --hard和git revert命令

    很多时候 xff0c git新手容易误操作 xff0c 比如 xff0c 在levelIISZ 1 4 dev分支下 xff0c 运行了git pull idc cpp 1 0的结果 xff0c 这样做麻烦很大 xff0c 经常导致mave
  • android 为什么需要签名

    所有的Android应用程序都要求开发人员用一个证书进行数字签名 xff0c anroid系统不会安装没有进行签名的由于程序 平时我们的程序可以在模拟器上安装并运行 xff0c 是因为在应用程序开发期间 xff0c 由于是以Debug面试进
  • 高通平台工具使用

    OverView QPST 综合工具 传输文件 查看 device 的 EFS 文件系统 代码烧录 QRCT 测试RF QXDM 看log JTAG trace32调试 QPST QXDM的使用说明 xff0c 具体的可以看我上传到csdn
  • git创建与管理远程分支

    1 远程分支就是本地分支push到服务器上的时候产生的 比如master就是一个最典型的远程分支 xff08 默认 xff09 1 git push origin master 除了master之外 xff0c 我们还可以随便创建分支 xf
  • pthread_key_t和pthread_key_create()详解

    下面说一下线程中特有的线程存储 xff0c Thread Specific Data 线程存储有什么用了 xff1f 他是什么意思了 xff1f 大家都知道 xff0c 在多线程程序中 xff0c 所有线程共享程序中的变量 现在有一全局变量