2809

14 分钟

#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_tvoid(*)(void*),调用时传入的参数为 tss_set 设置的值。

线程退出时(调用 thrd_exit 函数或线程入口函数返回),关联的线程局部存储会调用析构函数进行清理。

不再使用时需要通过 tss_delete 函数清理线程局部存储,这个函数不会调用析构函数。

参数

  • tss - 返回线程局部存储 ID
  • func - 线程局部存储的析构函数

返回值

  • 成功时返回 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)

创建于 2025/8/27

更新于 2025/8/27