回答
http://www.research.ibm.com/people/m/michael/pldi-2004.pdf
本文提出了一种完全无锁的内存分配器。它只使用广泛可用的操作系统支持和硬件原子指令。它提供了保证供应,即使在任意线程 终止和死机故障,并且它不受死锁不管调度策略,因此它甚至可以在中断处理程序和实时应用 使用 ,无需特殊的调度支持。此外,通过利用一些高层次的结构从囤积居奇,我们的分配 是高度可扩展性,空间的限制,以爆破一个常数因子, 并且能够避免错误共享的...
Depends中关于你的意思是效率。如果我关心的是让事情变得更快,那么我可能会让每个线程都有自己独立的内存池来处理,而自定义的“malloc”会从该池中获取内存。当然,如果我的担心是速度的话,我可能会首先避免分配。
没有一个答案;你会平衡一系列的担忧。这将是几乎不可能得到一个无锁分配器,但你可以早做很少的锁定(通过分配每个线程大池),也可以使锁又小又紧,他们必须是正确的。
+1谢谢。我更多地解释了效率。 – Viet 2010-01-03 19:01:39
请注意,每个线程池完全失败,生产者 - 消费者模型。 – 2011-07-12 21:00:27
可以使用无锁列表和一些不同大小的桶。
所以:
typedef struct
{
union{
SLIST_ENTRY entry;
void* list;
};
byte mem[];
} mem_block;
typedef struct
{
SLIST_HEADER root;
} mem_block_list;
#define BUCKET_COUNT 4
#define BLOCKS_TO_ALLOCATE 16
static mem_block_list Buckets[BUCKET_COUNT];
void init_buckets()
{
for(int i = 0; i < BUCKET_COUNT; ++i)
{
InitializeSListHead(&Buckets[i].root);
for(int j = 0; j < BLOCKS_TO_ALLOCATE; ++j)
{
mem_block* p = (mem_block*) malloc(sizeof(mem_block) + (0x1 << BUCKET_COUNT) * 0x8);
InterlockedPushEntrySList(&Buckets[i].root, &p->entry);
}
}
}
void* balloc(size_t size)
{
for(int i = 0; i < BUCKET_COUNT; ++i)
{
if(size <= (0x1 << i) * 0x8)
{
mem_block* p = (mem_block*) InterlockedPopEntrySList(&Buckets[i].root);
p->list = &Buckets[i];
}
}
return 0; // block to large
}
void bfree(void* p)
{
mem_block* block = (mem_block*) (((byte*)p) - sizeof(block->entry));
InterlockedPushEntrySList(((mem_block_list*)block)->root, &block->entry);
}
SLIST_ENTRY, InterlockedPushEntrySList, InterlockedPopEntrySList, InitializeSListHead
是在Win32下的无锁单链表操作的功能。在其他操作系统上使用相应的操作。
缺点:
- 架空的
sizeof(SLIST_ENTRY)
- 的桶只能在开始长出有效一次,之后就可以运行内存不足而不得不请求OS /桶等。 (其他桶导致碎片)
- 此示例有点太简单,必须扩展才能处理更多的案例
我想写在C.谢谢。 – Viet 2010-01-03 19:38:26
更新后的代码为C – Christopher 2010-01-03 20:09:56
太棒了!谢谢。 – Viet 2010-01-04 01:37:30
- 1. C++多线程:线程安全的内存分配
- 2. C# - 哪个更高效且线程安全?静态或即时课程?
- 3. 线程安全无锁
- 4. C:无锁内存分配库
- 5. c中线程的内存分配
- 6. C++中线程的内存分配
- 7. 是EventLog编写器线程安全
- 8. 在多线程C/C++中,malloc/new在分配内存时会锁定堆栈
- 9. C++/Linux:你如何编写一个使用套接字的线程安全库?
- 10. 线程安全与堆分配的内存
- 11. 这个C++代码如何安全且独立于编译器?
- 12. 高级C内存分配
- 13. 是std :: ifstream线程安全和无锁?
- 14. 线程安全无锁阵列
- 15. 线程安全,无锁增量功能?
- 16. 如何在C++应用程序中编译sqlite3线程安全?
- 17. 如何在线程安全执行中编写util.logger?
- 18. 在C++中,可以在一个线程中分配由另一个线程删除的内存吗?
- 19. 只有一个线程正在写入时的线程安全
- 20. 朱莉娅:高效的内存分配
- 21. 锁ILIST .NET线程安全
- 22. JVM上的内存分配无锁
- 23. 编写线程安全的载体
- 24. 如何:编写一个只能调用一次的线程安全方法?
- 25. 这种编码线程是否安全,死锁安全?
- 26. 使用读写器锁创建线程安全列表
- 27. 如何在C++中编写一个小内存泄漏检测?
- 28. 在C中编写一个安全的带标签的工会
- 29. 预分配的线程安全unordered_map
- 30. C中的线程安全?
+1感谢链接 – Viet 2010-01-03 19:19:29
本文是我想,当我看到这个问题的第一件事。我们在我们的产品中使用了这种分配器的变体,这真的非常有帮助。 – 2010-01-03 20:14:55
谢谢丹。这听起来很棒!所以我有信心改进它。 – Viet 2010-01-04 01:38:44