文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

使用C语言怎么对线程对象和线程进行存储

2023-06-08 00:34

关注

使用C语言怎么对线程对象和线程进行存储?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

C语言是什么

C语言是一门面向过程的、抽象化的通用程序设计语言,广泛应用于底层开发,使用C语言可以以简易的方式编译、处理低级存储器。

使用线程对象

线程对象是在声明中包含新存储类修饰符 _Thread_local 的全局或静态对象。这意味着:每一个线程拥有属于自己的线程对象实例,它在线程启动时创建并初始化。对象的存储周期等于线程的运行时间。在一个线程内表达式里面的线程对象名,将引用这个对象在当前线程下的本地实例。

修饰符 _Thread_local 可以与修饰符 static 或 extern 同时使用。头文件 threads.h 定义了 thread_local 作为 _Thread_local 的同义词。在例 1 中,主线程和新启动线程各自拥有线程本地变量 var 的一个实例。

【例1】使用一个线程对象

#include <stdio.h>#include <threads.h>thread_local int var = 10;void print_var(void){ printf("var = %d\n", var); }int func(void *);        // 线程函数int main(int argc, char *argv[]){  thrd_t th2;  if ( thrd_create( &th2, func, NULL ) != thrd_success ){   fprintf(stderr,"Error creating thread.\n"); return 0xff;  }  print_var();        // 输出:var = 10  thrd_join(th2, NULL);  return 0;}int func(void *arg)       // 线程函数{  var += 10;         // 线程本地变量  print_var();        // 输出:var = 20  return 0}

使用线程存储

线程存储技术要比线程对象更加灵活。例如,独立线程可以使用不同大小的内存。它们可以动态地分配内存,并通过调用析构函数再次释放内存。同时,可以使用相同的标识符访问这些独立线程所在的不同内存区域。

这种灵活性通过初始创建一个全局的键(key)实现,该键表示了一个指向线程存储的指针。然后,独立线程通过指定其线程存储的位置加载这个指针。该全局键值是类型为 tss_t 的对象。头文件 threads.h 包含了该类型的定义以及 4 个用于管理线程存储(简称 TSS)函数的声明:

int tss_create(tss_t*key,tss_dtor_t dtor);

通过析构函数 dtor 生成一个新的 TSS 指针,并且将 key 引用的对象设置为唯一标识该 TSS 指针的值。类型 tss_dtor_t 是一个函数指针,定义为 void(*)(void*)(它指的是一个函数指针,该函数参数为 void 指针,并且该函数没有返回值)。dtor 的返回值可以是一个空指针。

void tss_delete(tss_t key);

释放 TSS 键 key 所使用的所有资源。

int tss_set(tss_t key,void*val);

对于调用 tss_set()的线程,将 key 所标识的 TSS 指针设置为 val 所引用的内存地址。

void*tss_get(tss_t key);

返回指向内存块的指针,该内存块为正在调用的线程通过函数 tss_set()设置。如果发生错误,tss_get()返回 NULL。

如果函数 tss_create()和 tss_set()发生错误,则返回 thrd_error;否则,返回 thrd_success。

例 2 中的程序在动态分配的线程存储中,保留线程的名称。

【例2】使用线程存储

#include <threads.h>#include <stdio.h>#include <stdlib.h>#include <string.h>tss_t key;               // 用于TSS指针的全局键int thFunc(void *arg);     // 线程函数void destructor(void *data);  // 析构函数int main(void){  thrd_t th2, th3;  int result1 = 0, result2 = 0;  // 创建一个TSS密钥  if (tss_create(&key, destructor) != thrd_success)   return -1;  // 创建线程  if (thrd_create(&th2, thFunc, "Thread_1") != thrd_success     || thrd_create(&th3, thFunc, "Thread_2") != thrd_success)    return -2;  thrd_join(th2, &result1); thrd_join(th3, &result2);  if ( result1 != 0 || result2 != 0 )    fputs("Thread error\n", stderr);  else    puts("Threads finished without error.");  tss_delete(key);      // 释放TSS指针所有的资源  return 0;}void print(void)        // 显示线程存储{ printf( "print: %s\n", (char*)tss_get(key) );}int thFunc( void *arg ){  char *name = (char*)arg;  size_t size = strlen(name)+1;  // 设置线程存储  if ( tss_set(key, malloc(size)) != thrd_success )   return -1;  // 存储数据  strcpy((char*)tss_get(key), name);  print();  return 0;}void destructor(void *data){ printf("Destructor for %s\n", (char*)data); free(data);      // 释放内存}

关于使用C语言怎么对线程对象和线程进行存储问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注编程网行业资讯频道了解更多相关知识。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯