zoukankan      html  css  js  c++  java
  • thread_local变量(转)

    转自:https://www.cnblogs.com/pop-lar/p/5123014.html

    thread_local变量是C++11新引入的一种存储类型。它会影响变量的存储周期(Storage duration),有且只有thread_local关键字修饰的变量具有线程周期(thread duration),这些变量(或者说对象)在线程开始的时候被生成(allocated),在线程结束的时候被销毁(deallocated)。并且每一个线程都拥有一个独立的变量实例(Each thread has its own instance of the object)。thread_local可以和static与extern关键字联合使用,这将影响变量的链接属性(to adjust linkage)。(什么是链接属性?)

    那么,哪些变量可以被声明为thread_local?以下3类都是ok的:

    1. 命名空间下的全局变量。2. 类的static成员变量。3. 本地变量

    下面引用《C++ Concurrency in Action》书中的例子来说明这3种情况:

    thread_local int x;  //A thread-local variable at namespace scope
    class X
    {
      static thread_local std::string s; //A thread-local static class data member
    };
    static thread_local std::string X::s;  //The definition of X::s is required
    
    void foo()
    {
      thread_local std::vector<int> v;  //A thread-local local variable
    }
    

    既然每个线程都拥有一份独立的thread_local变量,那么就有2个问题需要考虑:

    1. 各线程的thread_local变量是如何初始化的
    2. 各线程的thread_local变量在初始化之后拥有怎样的生命周期,特别是被声明为thread_local的本地变量(local variables)

    下面的代码可以帮助回答这2个问题,我的测试环境是vs2015。

    输出的前3行打印能帮助解答thread_local变量是如何初始化的,可以看到每个线程都会进行一次初始化,例子中的g_n在主线程中最早被初始化为1,随后被修改为2和3,但这些修改操作并不影响g_n在线程t2和t3中的初始值(值为1),虽然t2和t3线程启动的时候主线程中的变量值已经被更新为3,所以主线程、thread1、thread2打印结果分别为3,2,2。

    后6行打印说明了一个事实,声明为thread_local的本地变量在线程中是持续存在的,不同于普通临时变量的生命周期,它具有static变量一样的初始化特征和生命周期,虽然它并没有被声明为static。例子中foo函数中的thread_local变量i在每个线程第一次执行到的时候初始化,在每个线程各自累加,在线程结束时释放。

    #include <thread>
    #include <iostream> thread_local int g_n = 1; void f() { g_n++; printf("id=%d, n=%d ", std::this_thread::get_id(),g_n); } void foo() { thread_local int i=0; printf("id=%d, n=%d ", std::this_thread::get_id(), i); i++; } void f2() { foo(); foo(); } int main() { g_n++; f(); std::thread t1(f); std::thread t2(f); t1.join(); //对应输出的前三行 t2.join(); std::cout << "---"; f2(); std::thread t4(f2); std::thread t5(f2); t4.join(); t5.join(); return 0; }

    输出(id值是每次运行时变的):

    id=8004, n=3
    id=8008, n=2
    id=8012, n=2

    ---

    id=8004, n=0
    id=8004, n=1
    id=8016, n=0
    id=8016, n=1
    id=8020, n=0
    id=8020, n=1

  • 相关阅读:
    什么是语义化的HTML?有何意义?为什么要做到语义化?
    Doctype作用?严格模式与混杂模式如何区分?它们有何差异?
    js和jq中常见的各种位置距离之offsetLeft和position().left的区别(四)
    js和jq中常见的各种位置距离之offset和offset()的区别(三)
    js和jq中常见的各种位置距离之offset()和position()的区别(二)
    js和jq中常见的各种位置距离之offsetLeft/clientLeft/scrollLeft (一)
    剖析js中的数据类型
    js数组去重几种方法
    SSE and Websocket
    鲜为人知的空元素╮(╯▽╰)╭
  • 原文地址:https://www.cnblogs.com/Key-Ky/p/8305139.html
Copyright © 2011-2022 走看看