栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

linux pthreads上的gcc 4.7-使用__thread的非平凡thread_local解决方法(无提升)

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

linux pthreads上的gcc 4.7-使用__thread的非平凡thread_local解决方法(无提升)

正如迈克所说

pthread_cleanup_push
的不合适。正确的方法是使用
pthread_key_create

我已经实现了一个小型演示程序,以演示如何执行此操作。我们实现

thread_local
您使用的宏,如下所示:

使用真正的C ++ 11功能,它将是:

void f(){    thread_local X x(1,2,3);    ...}

与此是:

void f(){    thread_local (X, x, 1, 2, 3);    ...}

与boost ::
thread_specifc_ptr之间的区别是动态内存分配为零。一切都与

__thread
持续时间一起存储。它的重量也轻得多,但特定于gcc /
linux。

概述:

  1. 我们曾经
    std::aligned_storage
    为变量创建__thread持续时间空间
  2. 从给定线程的第一个条目开始,我们使用placement new在存储中构造变量
  3. 我们还
    __thread
    为展示位置删除调用分配了一个链接列表条目
  4. 我们
    pthread_setspecific
    用来跟踪每个线程的列表头
  5. 传递给该函数的函数
    pthread_key_create
    会在线程退出时删除调用放置的列表。

#include <iostream>#include <thread>using namespace std;static pthread_key_t key;static pthread_once_t once_control = PTHREAD_ONCE_INIT;struct destructor_list{    void (*destructor)(void*);    void* param;    destructor_list* next;};static void execute_destructor_list(void* v){    for (destructor_list* p = (destructor_list*) v; p != 0; p = p->next)        p->destructor(p->param);}static void create_key(){    pthread_key_create(&key, execute_destructor_list);}void add_destructor(destructor_list* p){    pthread_once(&once_control, create_key);    p->next = (destructor_list*) pthread_getspecific(key);    pthread_setspecific(key, p);}template<class T> static void placement_delete(void* t) { ((T*)t)->~T(); }#define thread_local(T, t, ...)   T& t = *((T*)          ({              typedef typename aligned_storage<sizeof(T),                 alignment_of<T>::value>::type Storage;              static __thread bool allocated = false;      static __thread Storage storage;             static __thread destructor_list dlist;        if (!allocated)        {               new (&storage) T(__VA_ARGS__);               allocated = true;                 dlist.destructor = placement_delete<T>;                 dlist.param = &storage;           add_destructor(&dlist);       }            &storage;          }));class X{public:    int i;    X(int i_in) { i = i_in; cout << "X::X()" << endl; };    void f() { cout << "X::f()" << endl; }    ~X() { cout << "X::~X() i = " << i << endl; }};void g(){    thread_local(X, x, 1234);    x.f();}int main(){    thread t(g);    t.join();}

笔记:

  1. 您需要为每个pthread_ *调用添加错误检查。我只是将其删除以进行说明。
  2. 它使用
    __thread
    哪个是GNU扩展
  3. 它使用 表达式语句 将辅助__thread变量名称保留在父作用域之外。这也是GNU扩展。


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/397526.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号