在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(没有提升)所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)