这个问题的一些背景可能会有所帮助:我有用 C++ 编写的多线程应用程序,其中内存管理在性能方面是关键点。我已经实现了“主”分配器,假设它被称为“ManagedAllocator”。我也有自己的多平台线程本地存储支持,asm
使用fs
CPU 寄存器编写。所以基本上,现在我的全局运算符 new 看起来像这样:
void* operator new(Size_t memSize)
{
Thread_data& tls = get_thread_local_data();
ManagedAllocator* allocator = tls[TLS_INDEX_MANAGED_ALLOCATOR];
return allocator->AllocateMemory(memSize);
}
分配器的本地实例的创建和销毁由每个线程执行。与标准分配器(已经在 Win7/8、Linux、MacOS 和 WP8 上测试过(TLS 的实现略有不同)相比,它的工作原理非常好且超快)。
现在,问题:我有以下课程:
template < Size_t Alloc_size >
class FixedPoolAllocator
{
};
ManagedAllocator 在内部使用了这个类,但最近发现我还需要将它用作独立的分配器。但是,我不能以与 ManagedAllocator 相同的方式执行此操作,因为我需要为FixedPoolAllocator的每个特化使用 TLS 数组中的一个插槽。
然而,我不想玩锁,因为整个事情就是要进行无锁分配。有没有办法以一种干净、优雅的方式做到这一点?
* 更新 *
我忘了提一件事:我真正需要做什么。
我有简单的课程:
template < class Allocator >
class EXS_INTERFACE CustomAllocObject
{
public:
explicit CustomAllocObject();
~CustomAllocObject();
static void* operator new(Size_t memSize);
//also new[], placement versions, etc.
static void operator delete(void* memPtr);
//same as above
};
这只是:
template < class Allocator >
_EXSTemplateDef void*
CustomAllocObject<Allocator>::operator new(Size_t memSize)
{
return Allocator::AllocateMemory(memSize);
}
我用它来创建需要快速分配的对象:
class Image : public CustomAllocObject< FixedSizeAllocator<sizeof(ImageInternal)> >
{
};
AllocateMemory() 是每个分配器类中的静态函数。所以完美的解决方案是:
template < Size_t Alloc_size >
_EXSTemplateDef void*
FixedPoolAllocator<Alloc_size>::AllocateMemory(Size_t memSize)
{
FixedPoolAllocator<Alloc_size>* alloc = get_somehow_this_threads_instance();
return alloc->PerformAllocation();
}
问题是,我不能这样做:
template < Size_t Alloc_size >
class FixedPoolAllocator
{
//....
static EXS_THREAD_LOCAL FixedPoolAllocator<Alloc_size> _local_instance;
};
因为库被编译为 DLL。FixedPoolAllocator 在这种情况下是 DLL_EXPORT 类(这意味着它的所有静态成员也是)并且不允许使用 DLL_EXPORTed THREAD_LOCAL。