简体   繁体   English

堆栈说明 memory 分配 function - C++

[英]Explanation for stack memory allocation function - C++

I am trying to understand a program which uses multi-threading with shared-memory.我试图理解一个使用多线程和共享内存的程序。 The parent thread calls the following function and I don't quite understand how it works.父线程调用以下 function ,我不太明白它是如何工作的。

#define MAX_STACK_SIZE 16384  // 16KB  of stack

/*!
 * Writes to a 16 KB buffer on the stack. If we are using 4K pages for our
 * stack, this will make sure that we won't have a page fault when the stack
 * grows.  Also mlock's all pages associated with the current process, which
 * prevents the program from being swapped out.  If we do run out of
 * memory, the robot program will be killed by the OOM process killer (and
 * leaves a log) instead of just becoming unresponsive.
 */
void HardwareBridge::prefaultStack() {
  printf("[Init] Prefault stack...\n");
  volatile char stack[MAX_STACK_SIZE];
  memset(const_cast<char*>(stack), 0, MAX_STACK_SIZE);
  if (mlockall(MCL_CURRENT | MCL_FUTURE) == -1) {
    initError(
        "mlockall failed.  This is likely because you didn't run robot as "
        "root.\n",
        true);
  }
}
       
//Parent Thread
void HardwareBridge::run(){

  printf("[HardwareBridge] Init stack\n");
  prefaultStack();

  //printf("[HardwareBridge] Init scheduler\n");  // Commented because unrelated to current question
  //setupScheduler();
      
  // Calls multiple threads here
 
  for(;;){
  usleep(10000000);
  }
}

Can someone explain what's the purpose of this function.有人可以解释这个 function 的目的是什么。 Based on the comment, I could understand that it prevent the stack size from growing beyond 16KB.根据评论,我可以理解它可以防止堆栈大小超过 16KB。 However, the shared memory are predominantly allocated dynamically using new keyword in the program.但是,共享的 memory 主要是在程序中使用new关键字动态分配的。 Isn't dynamic memory allocation takes place in the heap rather than the stack?动态 memory 分配不是发生在堆中而不是堆栈中吗? How does the function helps in this scenario. function 如何在这种情况下提供帮助。

Based on the comment, I could understand that it prevent the stack size from growing beyond 16KB.根据评论,我可以理解它可以防止堆栈大小超过 16KB。

That's not what the comment says and not what the function does.这不是评论所说的,也不是 function 所做的。

Can someone explain what's the purpose of this function.有人可以解释这个 function 的目的是什么。

The comment explains it.评论解释了它。 The function does two things: function 做了两件事:

  • It pre-allocates 16K of stack.它预先分配了 16K 的堆栈。
  • It "locks" the allocated memory which prevents it from being swapped to disk.它“锁定”了分配的 memory 以防止它被交换到磁盘。

These two things guarantee that there won't be a page fault when the stack usage grows (as long as it doesn't grow beyond 16K).这两件事保证在堆栈使用量增长时不会出现页面错误(只要它不超过 16K)。

However, the shared memory are predominantly allocated dynamically然而,共享的 memory 主要是动态分配的

True.真的。 This means that shared, or other dynamic memory allocation is irrelevant to the function.这意味着共享或其他动态 memory 分配与 function 无关。

as per my understanding, the reply is inline据我了解,回复是内联的

  1. Based on the comment, I could understand that it prevent the stack size from growing beyond 16KB.根据评论,我可以理解它可以防止堆栈大小超过 16KB。

Nope.没有。 prefaultStack function has char[MAX_STACK_SIZE] on its stack, so stack segment of main process will be of size 4 pages + (stack size for main function). prefaultStack function 的堆栈上有char[MAX_STACK_SIZE] ,因此主进程的堆栈段大小为 4 页 +(主函数的堆栈大小)。 And any virtual memory pages of this process (along with any allocated in future as stack or heap grows) will not be swapped out to the swap area because mlockall is called with MCL_CURRENT and MCL_FUTURE https://linux.die.net/man/2/mlockall .并且此进程的任何虚拟 memory 页面(以及将来随着堆栈或堆增长而分配的任何页面)都不会被换出到交换区域,因为 mlockall 是用MCL_CURRENTMCL_FUTURE https://linux.die.net/man/ 调用2/mlockall This is the only functionality of this function.这是此 function 的唯一功能。 Nothing related to dynamic memory, heap or shared memory.与动态 memory、堆或共享 memory 无关。

  1. However, the shared memory are predominantly allocated dynamically using new keyword in the program.但是,共享的 memory 主要是在程序中使用 new 关键字动态分配的。

you are dealing with the multi-threading, so dynamic memory or heap address space is shared among the threads.您正在处理多线程,因此线程之间共享动态 memory 或堆地址空间。 This code does nothing with respect to shared memory between two processes.此代码对两个进程之间的共享 memory 没有任何作用。

  1. Isn't dynamic memory allocation takes place in the heap rather than the stack?动态 memory 分配不是发生在堆中而不是堆栈中吗? How does the function helps in this scenario. function 如何在这种情况下提供帮助。

Dynamic memory is allocated from the heap.动态 memory 从堆中分配。 And this function does not deal in any way with heap.而这个 function 不以任何方式处理堆。 This code only makes sure that all the stack and heap pages (CURRENT allocated and FUTURE allocated) of the process never swapped out to the swap area preventing any page faults which are time-consuming costlier operations.此代码仅确保进程的所有堆栈和堆页面(当前分配的和未来分配的)永远不会换出到交换区域,从而防止任何页面错误,这是耗时的昂贵操作。

In prefaultStack() you make sure that stack is incremented at least 16K from its previous size.prefaultStack()中,您确保堆栈从之前的大小至少增加了 16K。 Then by calling mlockall() you lock current memory pages to memory, preventing them from being swapped out.然后通过调用mlockall()将当前 memory 页面锁定到 memory,防止它们被换出。 After that you exit the function.之后,您退出 function。

I would say that the only real effect of this is that you ensure that no matter what, the calling thread will have at least 16K of stack available even if later on some hungry process eats up all remaining memory.我想说,这样做的唯一真正效果是确保无论如何,调用线程将至少有 16K 的可用堆栈,即使稍后某个饥饿的进程会吃掉所有剩余的 memory。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM