|
|
1
9
一般来说,您不需要担心内存分配器的线程安全性。所有标准的内存分配程序——也就是那些随MacOS、Windows、Linux等一起提供的程序——都是线程安全的。锁是提供线程安全性的标准方法,尽管可以编写只使用原子操作而不使用锁的内存分配器。 现在,这些内存分配器是否 规模 ;也就是说,它们的性能是否独立于执行内存操作的线程数?在大多数情况下,答案是否定的;他们要么放慢速度,要么可以消费 很多 更多的记忆。在两个维度(速度和空间)中,第一个可伸缩的分配器是 Hoard (我写过);mac os x分配器受到它的启发——并在文档中引用它——但是囤积更快。还有其他一些,包括谷歌的tcmalloc。 |
|
|
2
3
是的,支持多线程代码的“普通”堆实现必须包含某种锁,以确保正确的操作。在相当极端的条件下(a 许多 对于堆活动)这可能成为瓶颈;可以使用更专门的堆(通常提供某种线程本地堆),这有助于解决这种情况。我用过英特尔的TBB "scalable allocator" 到 good effect . tcmalloc 和 jemalloc 其他的malloc例子都是在考虑多线程伸缩的情况下实现的。 单线程和多线程感知malloc的时序比较 here . |
|
|
3
2
我发现 this 链接。 基本上,堆可以分为竞技场。当请求内存时,将依次检查每个竞技场,以查看它是否被锁定。这意味着不同的线程可以同时安全地访问堆的不同部分。自由有点复杂,因为每个自由都必须从分配给它的竞技场中释放出来。我认为一个好的实现将使不同的线程默认为不同的竞技场,以尽量减少争用。 |
|
4
2
这是一个操作系统问题,所以答案将取决于操作系统。 在窗户上,每个 过程 得到自己的堆。这意味着同一进程中的多个线程(默认情况下)共享一个堆。因此,操作系统必须对其分配和释放调用进行线程同步,以防止堆损坏。如果您不喜欢随后可能发生的争论,可以通过使用 Heap* routines . 你甚至可以重载MaloC(C)和新的(C++)来调用它们。 |
|
5
1
是的,通常必须锁定对堆的访问。当您有一个共享资源时,需要保护该资源;内存是一个资源。 |
|
|
6
0
这在很大程度上取决于您的平台/操作系统,但我相信这在主要系统上是可以的。C/C++不定义线程,所以默认情况下,我相信答案是“堆不受保护”,即必须为堆存取提供某种类型的多线程保护。 但是,至少在Linux和GCC中,我相信启用-pthread将自动为您提供这种保护… 此外,还有一个相关问题: |
|
|
NOBUD · 最大堆插入函数实现C++ 4 年前 |
|
|
JimBelushi2 · 合并排序创建内存堆 8 年前 |
|
|
Arda İbrahim Gökçe · 在遍历最小堆时获取垃圾值 8 年前 |
|
|
Alexy Grabov · 查找最大堆中k个最大元素的位置 8 年前 |
|
|
Maxxx · 使用堆在O(N log K)时间内查找前K个元素 8 年前 |
|
|
Karthik · 限制Go堆接口实现的优先级队列的大小 8 年前 |
|
|
mourinho · 使用数组实现最小堆[关闭] 8 年前 |