4

我需要在 Linux 下为 C++ 编写 Hoard 分配器。虽然算法很简单,但我不明白,在哪里(以及如何)存储分配器数据(例如堆)

这就是我的看法:分配器不是一个进程,它是一组函数,任何应用程序都可以使用。每个应用程序都有自己的堆。

  1. 发生了什么,应用程序何时启动?
  2. 分配器如何发现堆已经创建?
  3. 分配器如何创建、存储和销毁(关闭应用程序时)堆?
  4. 当函数被调用时,如何找出它运行在哪个线程(或哪个处理器上)?
4

3 回答 3

2
  1. 在应用程序启动期间可能不会发生太多事情,除非分配器被设计并连接到应用程序启动代码中以抢先从操作系统请求一些内存。
  2. 堆并没有真正创建。分配系统会在需要时向操作系统请求一些内存 - 用于初始设置或稍后需要额外的内存来完成请求的分配。在类 Unix 系统上,经常使用的系统调用称为sbrk. (严格来说,在 linux 上,sbrk它是系统调用的库函数包装器brk——这对你来说可能是也可能不是一个重要的区别。)
  3. sbrk分配器使用上述调用从操作系统获取内存。之后,它就可以自行管理该内存。当应用程序退出时,操作系统会回收内存——它知道它通过sbrk调用分发了什么,所以它知道它需要收回什么内存。
  4. 给定的代码在哪个线程或处理器上运行几乎无关紧要 - 如果您解释您所要求的内容的上下文,我会尝试回答。
于 2012-03-16T05:34:02.017 回答
1

你是什​​么意思“写囤积分配器”?有人已经写了这个分配器。您是否尝试从 C++中使用它?Emery Berger 的 Hoard 的内部工作原理在白皮书Hoard:多线程应用程序的可扩展内存分配器中进行了非常详细的描述。任何无法回答的问题始终可以通过阅读源代码或联系作者来解决。如果没有邮件列表,我会感到惊讶。

于 2012-03-16T07:04:51.797 回答
1

发生了什么,应用程序何时启动?

当应用程序启动时,分配器会自行初始化。如果您愿意,您可以在第一次调用分配器时执行此操作。

分配器如何发现堆已经创建?

我不确定我是否遵循这个问题。如果您正在谈论由使用此分配器的代码管理的堆,那么它会发现,因为它在创建堆时创建了跟踪条目。如果您正在谈论其他进程中的堆或由其他分配器创建的堆,它并不关心,因为它无论如何都不能使用这些堆。

分配器如何创建、存储和销毁(关闭应用程序时)堆?

通常,您有一个低级和高级分配器。低级分配器只是从操作系统获取原始内存块。确切的机制是特定于平台的。高级分配器管理堆,它从低级分配器获取内存来保存堆结构。

当函数被调用时,如何找出它运行在哪个线程(或哪个处理器上)?

您可以使用特定于线程的数据或调用特定于平台的“获取线程 ID”函数来找出哪个线程。至于哪个处理器,它是非常特定于平台的,并且在您获得它时信息可能已经过时了。大多数平台确实有这样的功能——请记住,您只能将其用作优化(以减少锁争用或提高缓存命中率)。至关重要的是,您不能使用它来绕过锁定,因为线程可以随时从一个处理器移动到另一个处理器。

但老实说,提供良好性能且可跨平台移植的内存分配确实是一个沉重的魔法案例。如果您不是该领域的专家,那么您不太可能开发出一种分配器来提供生产应用程序所需的性能和稳定性。

于 2012-09-14T21:09:52.363 回答