使用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语言怎么对线程对象和线程进行存储问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注亿速云行业资讯频道了解更多相关知识。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。