【问题标题】:Are stack allocations RT?堆栈分配是 RT 吗?
【发布时间】:2015-09-21 17:01:18
【问题描述】:

如果我在堆栈上分配一些东西,分配是确定性的(即 RT)吗?分配示例:

std::vector<double> desiredMobileState(13, 0.0);

我的意思是在堆上分配需要一个非确定性的系统调用(在一般情况下),因此应该禁止 RT 行为。

但是就 RT 行为而言,堆栈分配会发生什么?

【问题讨论】:

  • 不清楚你的代码 sn-p 是做什么用的,但要清楚的是,向量默认在堆上分配内存。
  • 为什么在堆上分配需要系统调用?哪个文档这么说的?
  • 我认为在非实时抢占式调度系统上没有什么是实时的。
  • @Dieter: RT = 确定性
  • @Ron Reba:系统显然被假定为 RT(例如:xenomai)

标签: c++ real-time allocation


【解决方案1】:

std::vector 对象本身是堆栈分配的,但该对象仅包含指向堆分配数据数组的指针。 (当然,C++ 标准从不使用“堆栈”或“堆”这两个词;上面这句话只是通常的实现。)因此分配容量为 13 的向量几乎肯定会涉及到堆分配。

然而,

在堆上分配需要系统调用(无论是什么系统)

不一定是这样。大多数堆分配不需要与系统进行任何交互。确实,在大多数系统上,一些堆分配需要系统调用(修改虚拟内存映射),因此它们不能被认为是实时的,但是很可能想象一个基于非虚拟内存的嵌入式系统,其中应用程序有固定的内存分配,malloc 要么放弃部分内存,要么失败。 [注1]

您可以使用自定义分配器从预先保留的池中分配内存区域,但为了保证 RT,您还需要确保预先保留的池是内存驻留的。


注意事项。

  1. 或者你可以只记得 DOS/Apple;无需生动的想象力。

【讨论】:

  • 有没有办法确保在启动应用程序时有“足够的物理内存”可用(即类似预保留内存的东西)?为了不被这一切所困扰......
  • @arennuit:这取决于您的操作系统。但通常有。
【解决方案2】:

当然,这都是实现定义的,但通常堆栈分配本身只是向堆栈指针添加一个常量值,因此这与向整数变量添加值一样具有确定性。

但是,通常还有其他操作通常与堆栈分配一起发生,这可能会导致其时间不确定。具体来说:

  • 运行构造函数例程来初始化分配的对象(构造函数当然可以做任何事情,这取决于相关类的作者在那里写的内容......例如,它可以分配堆内存,打开并读取文件,进入无限循环等)
  • 写入(和/或读取)新分配的堆栈内存,如果该内存区域尚未映射到物理 RAM,则可能导致页面错误。
  • 当然,总是存在堆栈溢出的可能性,这可能会导致分段错误(如果您幸运的话),或者只是随机的未定义行为和混乱(如果您不那么幸运的话)。

【讨论】:

    【解决方案3】:

    实际上堆栈分配也可能需要系统调用,您的线程堆栈可能已保留地址范围,但实际内存可能尚未提交。一旦您的代码尝试将堆栈内存用于某些物理内存的数组请求,可能会失败。

    所以为了超级安全——如果你想要的话,你必须只使用静态数组。据我所知,一些嵌入式系统禁止使用 malloc/free。

    【讨论】:

    • 我不确定我是否理解为什么在分配数组时不会遇到与内存请求相同的问题...
    • 您可以使用静态内存分配 - 它是在编译期间完成的,如果您的系统内存不足,那么您的应用程序将根本不执行,而不是在执行期间失败。当然,您可以通过在应用程序启动时预分配动态内存来实现类似的效果。
    猜你喜欢
    • 1970-01-01
    • 2012-07-29
    • 2019-10-25
    • 2014-05-13
    • 2012-06-26
    • 2011-10-06
    • 2011-02-11
    相关资源
    最近更新 更多