破坏Thread本地存储中的静态类成员 [英] Destruction of static class members in Thread local storage

查看:130
本文介绍了破坏Thread本地存储中的静态类成员的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在写一个快速的多线程程序,我想避免syncronization(需要同步的函数必须被称为像每秒5,000,000次,所以即使一个互斥量会太重)。

I'm writing a fast multi-thread program, and I want to avoid syncronization (the function which would need to be syncronized must be called something like 5,000,000 times per second, so even a mutex would be too heavy).

场景是:我有一个类的单个全局实例,每个线程都可以访问它。为了避免同步化,类中的所有数据都是只读的,除了一些类成员,然后在TLS(使用__thread或__declspec(thread))中声明。

The scenario is: I have a single global instance of a class, and each thread can access it. In order to avoid syncronization, all the data inside the class is accessed read-only, except for a bunch of class members, which are then declared in TLS (with __thread or __declspec(thread)).

不幸的是,为了使用编译器提供的__thread接口,类成员必须是静态的,没有构造函数/解构函数。我使用的类当然有自定义构造函数,所以我声明,作为类成员,指向这些类的指针(类似static __thread MyClass * _object)。

Unfortunately, in order to use the __thread interface offered by the compiler, the class members have to be static and without constructors/deconstructors. The classes I use of course have custom constructors, so I'm declaring, as class members, a pointer to that classes (something like static __thread MyClass* _object).

然后,第一次一个线程从全局实例调用一个方法,我会做一些像(if _object == NULL)object = new MyClass(...)。

Then, the first time a thread calls a method from the global instance, I'll do something like "(if _object == NULL) object = new MyClass(...)".

我最大的问题是:有没有聪明的方式释放这个分配的内存?这个全局类来自一个库,它被程序中的许多线程使用,并且每个线程以不同的方式创建(即每个线程执行不同的函数),并且我不能每次都放一个snipplet代码线程将要终止。
谢谢你们。

My biggest problem is: is there a smart way to free this allocated memory? This global class is from a library, and it is used by many threads in the program, and each thread is created in a different way (i.e. each thread executes a different function) and I can't put a snipplet of code each time the thread is going to terminate. Thank you guys.

推荐答案

如果你只是想要一个通用的清理函数,你仍然可以使用boost thread_specific_ptr。您不需要实际使用存储在那里的数据,但您可以利用自定义清理功能。只是让这个函数是任意的,你可以做任何你想要的。查看用于直接pthreads函数调用的pthread函数 pthread_key_create

If you just want a generic cleanup function you can still use boost thread_specific_ptr. You don't need to actually use the data stored there, but you can take advantage of the custom cleanup function. Just make that function something arbitrary and you can do whatever you want. Look at the pthread function pthread_key_create for a direct pthreads function call.

有一个不幸的是没有容易的答案,至少不是我碰到了。也就是说,没有常见的方法可以在线程退出时删除复杂的对象。但是,没有什么能阻止你自己这样做。

There is unfortunately no easy answer, at least not that I've come across yet. That is, there is no common way to have complex objects deleted at thread exit time. However, there's nothing stopping you from doing this on your own.

你需要在线程退出时注册自己的处理程序。使用pthreads pthread_cleanup_push 。我不知道它是在窗户上。这当然不是跨平台的。但是,可能你完全控制线程的启动及其入口点。你可以简单地从你的线程返回之前显式调用一个清理函数。我知道您提到您无法添加此代码段,在这种情况下,您将离开调用操作系统特定的函数来添加清除例程。

You will need to register your own handlers at thread exit time. With pthreads that would be pthread_cleanup_push. I don't know what it is on windows. This is of course not cross-platform. But, presumably you have full control of the starting of the thread and its entry-point. You could simply explicitly call a cleanup function just before returning from your thread. I know you mentioned you can't add this snippet, in which case you'll be left calling the OS specific function to add a cleanup routine.

显然,为所有分配的对象创建清理函数可能很烦人。所以,你应该创建一个更多的线程局部变量:对象的析构函数列表。对于你创建的每个线程特定的变量,你将一个析构函数推到这个列表。这个列表必须根据需要创建,如果你没有一个共同的线程入口点:有一个全局函数调用它需要你的析构函数并创建列表如有必要,然后添加析构函数。

Obviously creating cleanup functions for all objects allocated could be annoying. So instead you should create one more thread local variable: a list of destructors for objects. For each thread-specific variable you create you'll push a destructor onto this list. This list will have to be created on demand if you don't have a common thread entry point: have a global function to call which takes your destructor and creates the list as necessary, then adds the destructor.

这个析构函数看起来像是取决于你的对象层次结构(你可能有简单的boost bind语句,shared_ptr的,基类中的虚拟析构函数或其组合)。

Exactly what this destructor looks like depends heavily on your object hierarchy (you may have simple boost bind statements, shared_ptr's, a virtual destructor in a base class, or a combination thereof).

您的通用清除函数可以遍历此列表并执行所有析构函数。

Your generic cleanup function can then walk through this list and perform all the destructors.

这篇关于破坏Thread本地存储中的静态类成员的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆