C/C++ 线程局部存储(TLS)

在C或C++中,线程局部存储(Thread-Local Storage,简称TLS)是一种用于存储线程特有数据的方法。这意味着每个线程都可以访问它自己的变量实例,而不会影响到其他线程中的同名变量。这在多线程程序中非常有用,因为它可以避免对共享数据的竞争和同步开销。

C++11引入了thread_local关键字来简化线程局部存储的使用。在C中,则需要依赖操作系统或编译器提供的特定机制,如GCC的__thread关键字。

C++11中的thread_local示例

下面是一个C++11中使用thread_local的简单例子:

cpp 复制代码
#include <iostream>
#include <thread>
#include <vector>

// 定义一个线程局部的整型变量
thread_local int tls_counter = 0;

void increment_counter() {
    tls_counter++; // 每个线程都会独立地增加自己的tls_counter
    std::cout << "Thread " << std::this_thread::get_id() << " incremented tls_counter to " << tls_counter << std::endl;
}

int main() {
    std::vector<std::thread> threads;

    // 创建10个线程
    for (int i = 0; i < 10; ++i) {
        threads.emplace_back(increment_counter);
    }

    // 等待所有线程完成
    for (auto& th : threads) {
        th.join();
    }

    return 0;
}

输出:

txt 复制代码
Thread 140517560022592 incremented tls_counter to 1
Thread 140517551629888 incremented tls_counter to 1
Thread 140517534844480 incremented tls_counter to 1
Thread 140517543237184 incremented tls_counter to 1
Thread 140517409019456 incremented tls_counter to 1
Thread 140517526451776 incremented tls_counter to 1
Thread 140517518059072 incremented tls_counter to 1
Thread 140517438387776 incremented tls_counter to 1
Thread 140517429995072 incremented tls_counter to 1
Thread 140517421602368 incremented tls_counter to 1

在这个例子中,tls_counter是一个线程局部变量,每个线程都会拥有自己的tls_counter实例。因此,尽管所有线程都调用了increment_counter函数,但每个线程都会独立地增加自己的tls_counter,而不会影响到其他线程的tls_counter

GCC的__thread在C中的示例

对于C语言,可以使用GCC的__thread关键字来实现类似的功能:

c 复制代码
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>

// 定义一个线程局部的整型变量
__thread int tls_counter = 0;

void* increment_counter(void* arg) {
    tls_counter++; // 每个线程都会独立地增加自己的tls_counter
    printf("Thread %ld incremented tls_counter to %d\n", (long)pthread_self(), tls_counter);
    return NULL;
}

int main() {
    pthread_t threads[10];

    // 创建10个线程
    for (int i = 0; i < 10; ++i) {
        pthread_create(&threads[i], NULL, increment_counter, NULL);
    }

    // 等待所有线程完成
    for (int i = 0; i < 10; ++i) {
        pthread_join(threads[i], NULL);
    }

    return 0;
}
txt 复制代码
Thread 127565616375360 incremented tls_counter to 1
Thread 127565599589952 incremented tls_counter to 1
Thread 127565624768064 incremented tls_counter to 1
Thread 127565582804544 incremented tls_counter to 1
Thread 127565607982656 incremented tls_counter to 1
Thread 127565591197248 incremented tls_counter to 1
Thread 127565574411840 incremented tls_counter to 1
Thread 127565477959232 incremented tls_counter to 1
Thread 127565486351936 incremented tls_counter to 1
Thread 127565494744640 incremented tls_counter to 1

这个例子与C++的例子类似,但使用了C的pthread库来创建和管理线程,并使用__thread关键字来声明线程局部变量。

注意,虽然__thread在GCC中非常有用,但它并不是C语言标准的一部分,因此在使用时需要考虑跨平台兼容性问题。

相关推荐
草莓熊Lotso3 小时前
【洛谷题单】--分支结构(三)
c语言·c++·刷题·洛谷
GetcharZp4 小时前
C++日志库新纪元:为什么说spdlog是现代C++开发者必备神器?
c++·后端
Algebraaaaa4 小时前
为什么C++主函数 main 要写成 int 返回值 | main(int argc, char* argv[]) 这种写法是什么意思?
开发语言·c++
fqbqrr8 小时前
2508C++,检测S模式
c++
专注VB编程开发20年10 小时前
IIS Express中可以同时加载并使用.net4.0和.NET 2.0的 DLL
c++·windows·microsoft·c#·vb.net
xiaobobo333010 小时前
C语言中关于普通变量和指针变量、结构体包含子结构体或包含结构体指针的一些思考
c语言·开发语言·结构体指针
光头闪亮亮10 小时前
C++凡人修仙法典 - 散修版
c++
时光の尘12 小时前
ESP32入门开发·VScode空白项目搭建·点亮一颗LED灯
c语言·ide·vscode·freertos·led·esp32-s3·esp32-idf
John.Lewis12 小时前
数据结构初阶(8)二叉树的顺序结构 && 堆
c语言·数据结构·算法
程序猿编码13 小时前
基于LLVM的memcpy静态分析工具:设计思路与原理解析(C/C++代码实现)
c语言·c++·静态分析·llvm·llvm ir