首页 > 其他分享 >C语言thread_local关键字

C语言thread_local关键字

时间:2024-12-25 14:43:52浏览次数:4  
标签:thread int thrd C语言 线程 C11 local

GNU C语言的"__thread"与C11关键字_Thread_local等效,这里只说一下C11的。

#define thread_local _Thread_local  //(since C11, then removed in C23)

Since C23, thread_local is itself a keyword, which may also be a predefined macro, so <threads.h> no longer provides it.

需要说明的是,c11引入的_Thread_local关键字在c23标准中可以直接使用thread_local ,也即c23标准_Thread_local关键字被废弃了。

有且只有 thread_local 关键字修饰的变量具有线程(thread)周期,这些变量在线程开始的时候被生成,在线程结束的时候被销毁,并且每一个线程都拥有一个独立的变量实例。

thread_local 一般用于需要保证线程安全的函数中。

以下部分在一些编译器中还没有实现。

在标准的 C 语言规范中,对线程的支持迟迟没有出现,终于在 C11 中实现了。在此之前,POSIX 线程 API 被用作利用多线程编程的主要工具。由于 C11 提供了更标准的接口,可以在不依赖平台的情况下使用,因此建议使用 ISO 语言 API,而不要使用 POSIX 版本。尽管这两个 API 的功能原型不匹配,但主要功能大多相似。在下面的示例中,我们演示了一个简单的场景,其中启动了四个线程来执行 printHello 函数,然后在不加入主线程的情况下终止该线程。

thrd_create 接受三个参数,

  1. 第一个是指向线程标识符的指针。
  2. 第二个参数的类型为 thrd_start_t,对于函数指针原型而言,其名称仅为 typedef
  3. 第三个参数指定可以传递给函数的参数。

使用枚举值定义 thrd_create 的返回状态代码:thrd_successthrd_nomem 和 thrd_error

thrd_join 是 pthread_join 函数的一个类比,它将阻塞当前线程,直到给定线程完成执行。它带有两个参数:线程标识符和 int 指针,表示如果用户提供有效地址,则可以选择存储返回状态代码的位置。如果在已经分离或联接的线程上调用 thrd_join,则结果是未定义的行为。该函数返回对应于 thrd_success 或 thrd_error 的值。

下一个示例代码实现了四个线程递增 atomic_int 类型变量的情况。最后,等待其他线程完成的主线程将打印 counter 的最终总和值。

#include <stdatomic.h>
#include <stdio.h>
#include <stdlib.h>
#include <threads.h>
#include <unistd.h>

#ifndef NUM_THREADS
#define NUM_THREADS 4
#endif

atomic_int counter = 0;

enum { MAX_ITER = 1000 };

void *printHello(void *thr_id) {
  long tid;
  tid = (long)thr_id;
  printf("thread %ld started incrementing ID - %lu\n", tid, thrd_current());

  for (int i = 0; i < MAX_ITER; ++i) {
    counter += 1;
  }

  return NULL;
}

int main(int argc, char const *argv[]) {
  thrd_t threads[NUM_THREADS];
  int rc;
  long t;

  for (t = 0; t < NUM_THREADS; t++) {
    rc = thrd_create(&threads[t], (thrd_start_t)printHello, (void *)t);
    if (rc == thrd_error) {
      printf("ERORR; thrd_create() call failed\n");
      exit(EXIT_FAILURE);
    }
  }

  for (t = 0; t < NUM_THREADS; t++) {
    thrd_join(threads[t], NULL);
  }
  printf("count = %d\n", counter);

  thrd_exit(EXIT_SUCCESS);
}

输出

 

 

参考资料:

1. thread_local

2. C11 GCC threads.h not found

 

标签:thread,int,thrd,C语言,线程,C11,local
From: https://www.cnblogs.com/tryst/p/18630353

相关文章

  • Spring 中的 LocalSessionFactoryBean和LocalContainerEntityManagerFactoryBean
    Spring中的LocalSessionFactoryBean和LocalContainerEntityManagerFactoryBean|Id|Title|DateAdded|SourceUrl|PostType|Body|BlogId|Description|DateUpdated|IsMarkdown|EntryName|CreatedTime|IsActive|AutoDesc|AccessPermission||-------......
  • 鸿蒙Next状态管理V2-Local装饰器总结
    一、引言在鸿蒙Next的开发中,状态管理是构建高效、响应式应用的关键部分。@Local装饰器作为状态管理V2中的重要特性,为开发者提供了一种有效的方式来管理组件内部状态。本文将对@Local装饰器进行全面总结,包括其功能、使用方法、与@State装饰器的对比以及常见问题的解决方法等。二......
  • A5-1密码算法C语言实现
    #include<iostream>usingnamespacestd;boolx1[19]={0};//用于LFSR_1的向量boolx2[22]={0};//用于LFSR_2的向量boolx3[23]={0};//用于LFSR_3的向量boolkey[......
  • 4、数据结构与算法解析(C语言版)--栈
    栈的数据存储遵循“后进先出的规则”,这在计算机里面是非常有用的,比如word等编辑软件的"撤销"功能,就是使用栈进行实现的。1、创建项目 main.h#ifndef_MAIN_H#define_MAIN_H#include<stdio.h>#include<stdlib.h>#include<time.h>#defineTRUE1#defineFALSE0......
  • C语言中常见的数据类型及其处理方式
    1.数据类型整型整型所占字节int4字节unsignedint0~2^32-1signedint-2^31~2^31-1short2字节unsignedshort0~65535signedshort-32768~32767long8字节unsignedlong0~2^32-1signedlong-2^31~2^31-1longlong8字节unsingnedlo......
  • C语言——整型数据在内存中的存储
    整型数组在内存中的存储一、大小端存储1.大端存储(大端字节序存储)2.小端存储(小端字节序存储)>给大家一个题目,设计一个程序判断当前机器的字节序.二、原码、反码和补码1.*补充2.例题1.2.3.4.5.6.一、大小端存储1.大端存储(大端字节序存储)将一个数据的低位字节内容......
  • Threadlocal(一):用户会话管理重构 “神器”,新手破局,老手重构升维之选!
    提到前面:一个热衷技术,反对八股的资深研发,不卖课不引流,专注分享高质量教学博客。如果觉得文章还不错的话,可以点赞+收藏+关注支持一下,持续分享高质量技术博客。如果有什么需要改进的地方还请大佬指出❌欢迎学习交流,直接私我引言面试的时候是不是经常被问到并发编程?是......
  • 【已解决】错误:未添加头文件(C语言经验分享)
    以上程序出现报错[Warning]incompatibleimplicitdeclarationofbuilt-infunction'strcspn'[Warning]incompatibleimplicitdeclarationofbuilt-infunction'strlen'cannotopenoutputfileC:Users#JlDesktoplcl1.1.1.exe:Permissiondenied[Err......
  • 【C语言】[waring]comparison between pointer and integer报错
     原因:在C语言中,指针和整型是不同的数据类型,它们之间不能直接进行比较。 改正:在arr[i]前加&取地址  [waring]comparisonbetweenpointerandinteger改正方法:1.显式类型转换(不推荐)intvalue=10;int*ptr=NULL;if((int)ptr==value){}这里if((int)ptr......
  • C语言学生管理系统|结构体数组+文件操作+按照姓名排序
    也是第一次使用Markdown语法orz定义结构体structstudent{charname[10];charsex[5];intage;intnum;intscore[5];//需要储存五门课的成绩};structclass{structstudentst[50];//最大可存储50个学生信息intn;};主菜单函数......