gcc 4.7在Linux pthreads– 非常规thread_local解决方法使用__thread(没有提升)

gcc 4.7在Linux pthreads– 非常规thread_local解决方法使用__thread(没有提升),第1张

概述gcc 4.7在Linux pthreads – 非常规thread_local解决方法使用__thread(没有提升

在C ++ 11中,可以使用thread_local存储来创build一个非平凡的对象:

class X { ... } voID f() { thread_local X x = ...; ... }

不幸的是,这个function还没有在gcc中实现(从4.7开始)。

海湾合作委员会确实允许你有线程局部variables,但只有琐碎的types。

我正在寻找一个解决方法:

当一个二进制文件运行时,它是否将其整个二进制数据一次性复制到内存中? 我可以改变吗?

libusb-1.0 hotplug事件在fork()之后在parent中停止工作,当child调用libusb_exit()

如何通过蓝牙从iPhone / iPod touch发送stream数据到windows C ++应用程序?

执行时间:GetFrontBufferData,GetBackBuffer,GetrendertargetData

该进程无法访问该文件,因为它正在被另一个进程使用

这是我到目前为止:

#include <iostream> #include <type_traits> using namespace std; class X { public: X() { cout << "X::X()" << endl; }; ~X() { cout << "X::~X()" << endl; } }; typedef aligned_storage<sizeof(X),alignment_of<X>::value>::type XStorage; inline voID placement_delete_x(X* p) { p->~X(); } voID f() { static __thread bool x_allocated = false; static __thread XStorage x_storage; if (!x_allocated) { new (&x_storage) X; x_allocated = true; // Todo: add thread cleanup that // calls placement_delete_x(&x_storage) } X& x = *((X*) &x_storage); } int main() { f(); }

我需要帮助的是在当前线程退出时调用placement_delete_x(&x_storage)。 有没有一种机制在pthreads和/或linux我可以用来做到这一点? 我需要添加一个函数指针和一个参数的某种pthread清理堆栈?

更新:

我认为pthread_cleanup_push可能是我想要的:

http://www.kernel.org/doc/man-pages/online/pages/man3/pthread_cleanup_push.3.HTML

这是否会在正确的情况下调用清理处理程序?

更新2:

它看起来像boost::thread_specific_ptr最终调用pthread_key_create destructor参数,而不是pthread_cleanup_push – 调用它的tls清理function:

http://pubs.opengroup.org/onlinepubs/009696799/functions/pthread_key_create.HTML

目前还不清楚这两种方法之间有什么区别,如果有的话。 ?

如何在命令行的语言环境中显示文本?

在linux上堆栈溢出沉默?

Cygwin编译错误:“这个应用程序已经请求运行时以不寻常的方式终止它”

GetSyscolorBrush常数的选项卡控件的背景颜色?

为什么这个循环会毁掉我的记忆?

pthread_key_create和朋友是你想要使用析构函数实现线程特定的类型变量。 但是,这些通常需要您管理创建和销毁变量的整个过程,我不确定是否可以将它们与__thread结合使用。

pthread_cleanup_push不适合。 如果线程在使用该资源的(短)代码块期间退出,则允许释放资源; 如链接到的文档中所述,它必须与该函数的同一级别的pthread_cleanup_pop匹配,并且如果线程从其主函数返回,则不会调用该处理程序。 这意味着如果你希望线程局部变量在对函数的调用之间保持不变,就不能使用它。

对于那些不禁止使用第三方库的人来说, Boost提供了一种便捷的方式来管理线程本地存储。

正如Mike所说, 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,3); ... }

这个和boost :: thread_specifc_ptr之间的区别在于没有动态内存分配。 所有内容都以__thread持续时间存储。 它也明显更轻,但它是特定于gcc / linux的。

概述:

我们使用std::aligned_storage为变量创建__thread持续时间空间

在给定线程的第一个条目中,我们使用placement new来构造存储中的变量

我们还__thread分配一个链接列表条目的位置删除调用

我们使用pthread_setspecific来跟踪每个线程列表头

传递给pthread_key_create的函数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,1234); xf(); } int main() { thread t(g); t.join(); }

笔记:

您需要为每个pthread_ *调用添加错误检查。 我刚刚删除它的说明。

它使用__thread这是一个GNU扩展

它使用表达式语句将辅助__thread变量名称保留在父范围之外。 这也是一个GNU扩展。

总结

以上是内存溢出为你收集整理的gcc 4.7在Linux pthreads – 非常规thread_local解决方法使用__thread(没有提升)全部内容,希望文章能够帮你解决gcc 4.7在Linux pthreads – 非常规thread_local解决方法使用__thread(没有提升)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1271100.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-08
下一篇 2022-06-08

发表评论

登录后才能评论

评论列表(0条)

保存