C++-如何避免线程堆冲突问题?
系统运行时库使用锁定的方式同步对堆的访问,因此从系统堆分配内存的操作成本非常高。对于锁的争用限制了多线程的性能优势,如何更好的解决这个问题,提高并发系统的性能。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
系统运行时库使用锁定的方式同步对堆的访问,因此从系统堆分配内存的操作成本非常高。对于锁的争用限制了多线程的性能优势,如何更好的解决这个问题,提高并发系统的性能。
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(3)
服务器为了提高运行性能,采取了一种内存池的分配方式来提高性能,可以解决你说的问题。核心思想是由程序自己来进行内存的分配和处理。比如首先在程序启动的时候分配一大块内存,确定好内存分配和释放的方式。不同的服务程序对内存使用的方式有不同,根据这些情况来制定不同的分配和管理方式。
若都是读取操作无需考虑,只要有一个写操作,就需要避免冲突。可以使用以下几种策略:
1.使用信号量同步代替全局变量同步。
2.尽量使用局部变量代替全局变量。
3.尽量减少锁暂用时间。
4.不同的全局堆使用不同的锁。
的确像你说的,如果过度使用同步机制会加大系统堆的操作成本,影响了多线程的优势。我们以前专门研究过这个问题,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
}