通过使用关键字thread_local,可以定义线程本地数据。
thread_local
在必要的情况下,我们可以为每个线程创建线程本地数据。
线程局部数据专属于线程,其行为类似于静态数据。
这意味着,它将在第一次使用时创建,其生命周期将绑定到线程的生命周期。
线程本地数据通常称为线程本地存储。
使用线程本地数据非常简单,下面是个小程序:
// threadLocal.cpp
#include <iostream>
#include <string>
#include <mutex>
#include <thread>
std::mutex coutMutex;
thread_local std::string s("hello from ");
void addThreadLocal(std::string const& s2){
s+=s2;
// 加锁是为了保护 std::cout 输出正常
std::lock_guard<std::mutex> guard(coutMutex);
std::cout << s << std::endl;
std::cout << "&s: " << &s << std::endl;
std::cout << std::endl;
}
int main(){
std::cout << std::endl;
std::thread t1(addThreadLocal,"t1");
std::thread t2(addThreadLocal,"t2");
std::thread t3(addThreadLocal,"t3");
std::thread t4(addThreadLocal,"t4");
t1.join();
t2.join();
t3.join();
t4.join();
}
通过在第8行中使用关键字thread_local,创建线程局部字符串s。
线程t1-t4(第27-30行)使用函数addThreadLocal(第12-21行)作为其工作包task。
线程分别得到字符串“t1”到“t4”作为参数,并将它们添加到thread_local字符串s中。
此外,addThreadLocal在第 18行中打印字符串s的地址。
打印结果如下:
程序结果的输出在第17行隐式显示,字符串地址在第18行显式显示。
程序执行中实际上是为每个字符串s创建了一个thread-local类型的字符串。
首先,每个输出一个新的thread-local字符串,其次,每个字符串s具有不同的地址。
原文地址:http://www.modernescpp.com/index.php/thread-local-data