如何避免线程堆冲突问题?


系统运行时库使用锁定的方式同步对堆的访问,因此从系统堆分配内存的操作成本非常高。对于锁的争用限制了多线程的性能优势,如何更好的解决这个问题,提高并发系统的性能。

多线程 C++

sybdcz 12 years, 2 months ago

的确像你说的,如果过度使用同步机制会加大系统堆的操作成本,影响了多线程的优势。我们以前专门研究过这个问题,windows里API里有 HeapCreate ,可以专门为多线程分配独立堆,这里有一些技巧,比如堆句柄可存储在TLS中(线程独立存储),当线程分配或释放内存时随时使用该堆。
MSDN有详细的描述,你可以参考一下

   
  [HeapCreate][1]
  
另外,这种堆必须保证谁执行谁释放,否则会导致Crash出现
static DWORD tls_key;
__declspec(dllexport) void *
thr_malloc( size_t n )
{
return HeapAlloc( TlsGetValue( tls_key ), 0, n );
}

__declspec(dllexport) void
thr_free( void *ptr )
{
HeapFree( TlsGetValue( tls_key ), 0, ptr );
}
// 此例使用了WIN32编程API的多项特性
// 它使用了一个.DLL 模块来实现待记录线程的创建和销毁

BOOL WINAPI DllMain(
HINSTANCE hinstDLL, // 交给DLL 模块
DWORD fdwReason, //函数调用原因
LPVOID lpReserved ) // 预定
{
switch( fdwReason ) {
case DLL_PROCESS_ATTACH:
// 使用线程本地存储来记忆堆
tls_key = TlsAlloc();
TlsSetValue( tls_key, GetProcessHeap() );
break;

case DLL_THREAD_ATTACH:
//使用 HEAP_NO_SERIALIZE 来避免锁开销
TlsSetValue( tls_key, HeapCreate( HEAP_NO_SERIALIZE, 0, 0 ) );
break;
case DLL_THREAD_DETACH:
HeapDestroy( TlsGetValue( tls_key ) );
break;
case DLL_PROCESS_DETACH:
<coding-4 lang="other">
TlsFree( tls_key );
break;
}
return TRUE; // 成功的 DLL_PROCESS_ATTACH
}

沙耶夜夜夜 answered 12 years, 2 months ago

Your Answer