#C 语言标准库函数 tss_create
/*********************************************
* @brief 创建线程局部存储
* @param[out] tss 返回线程局部存储 ID
* @param func 线程局部存储的析构函数
* @return 是否成功
********************************************/
int tss_create(tss_t* tss, tss_dtor_t func);
说明
创建线程局部存储,通过参数 tss
返回线程局部存储 ID。
线程局部存储只需创建一次,即可在多个线程中使用,每个线程中绑定的值都是独立的。
参数 func
是线程局部存储的析构函数,其类型 tss_dtor_t
是 void(*)(void*)
,调用时传入的参数为 tss_set 设置的值。
线程退出时(调用 thrd_exit 函数或线程入口函数返回),关联的线程局部存储会调用析构函数进行清理。
不再使用时需要通过 tss_delete 函数清理线程局部存储,这个函数不会调用析构函数。
参数
tss
- 返回线程局部存储 IDfunc
- 线程局部存储的析构函数
返回值
- 成功时返回
thrd_success
- 失败时返回
thrd_error
#示例
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <threads.h>
// 线程局部存储的析构函数
void dtor(void* data)
{
printf("析构函数\n");
// 读取 data
printf("%s\n", (char*)data);
// 释放 data
free(data);
}
// 线程入口函数1
int func1(void* data)
{
// 通过参数传入 tss
tss_t* tss = (tss_t*)data;
// 将 ptr 写入线程局部存储
void* ptr = malloc(64);
tss_set(*tss, ptr); // 析构函数的参数为 ptr
// 向 ptr 写数据
strcpy(ptr, "hello world");
return 0;
}
// 线程入口函数2
int func2(void* data)
{
// 通过参数传入 tss
tss_t* tss = (tss_t*)data;
// 将 ptr 写入线程局部存储
void* ptr = malloc(64);
tss_set(*tss, ptr); // 析构函数的参数为 ptr
// 向 ptr 写数据
strcpy(ptr, "happy days");
return 0;
}
int main(void)
{
// 创建线程局部存储
tss_t tss;
tss_create(&tss, dtor);
// 创建线程
thrd_t th1, th2;
thrd_create(&th1, func1, &tss); // 通过参数传入 tss
thrd_create(&th2, func2, &tss);
// 等待线程结束
thrd_join(th1, NULL);
thrd_join(th2, NULL);
// 删除线程局部存储
// 这里只会清理 tss,但不会清理 ptr
tss_delete(tss);
return 0;
}
运行结果:
析构函数 hello world 析构函数 happy days
说明:
线程局部存储在主线程中创建,传递给子线程使用;子线程分别设置存储的值,相互独立,互不干扰。
线程 1 和线程 2 结束时,分别调用析构函数,通过 free 释放 malloc 分配的内存空间。
在线程 1 和线程 2 结束后,调用 tss_delete 函数清理线程局部存储。
#推荐阅读
#参考标准
- C17 standard (ISO/IEC 9899:2018):
- 7.26.6.1 The tss_create function (p: 281-282)
- C11 standard (ISO/IEC 9899:2011):
- 7.26.6.1 The tss_create function (p: 386)