线程中的堆栈大小在C ++中定义了什么?

时间:2015-11-14 10:42:24

标签: c++ multithreading winapi stack

我在源代码中使用C ++和Windows.h.我在MSDN中阅读了CreateThread API,但我仍然不明白指定堆栈大小的本质。默认情况下,它是1 MB。但是如果我指定32个字节会发生什么?

线程中的堆栈大小定义了什么?

请提供详尽的解释,我将不胜感激。感谢。

3 个答案:

答案 0 :(得分:18)

堆栈用于存储局部变量,在函数调用中传递参数,存储返回地址。线程的堆栈具有固定的大小,该大小在创建线程时确定。这也是你所指的价值。

堆栈大小是在创建线程时确定的,因为它需要占用连续的地址空间。这意味着必须在创建线程时保留线程堆栈的整个地址空间。

如果堆栈太小则可能溢出。这是一个称为堆栈溢出的错误情况,本网站以此名称命名。当您调用某个函数时,会发生以下部分或全部:

  • 将参数压入堆栈。
  • 将返回地址压入堆栈。
  • 创建包含函数局部变量空间的堆栈帧。

所有这些都消耗了堆栈中的空间。当函数依次调用另一个函数时,会消耗更多的堆栈空间。随着调用堆栈的深入,需要更多的堆栈空间。

因此,将堆栈大小设置得过低会导致堆栈耗尽并溢出。这是您无法恢复的终端条件。当然,32个字节(向上舍入到一个页面,即4096个字节)对于几乎所有线程来说都太小了。

如果你有一个包含大量线程的程序,并且你知道线程不需要保留1MB的堆栈大小,那么使用较小的堆栈大小会有好处。这样做可以避免耗尽可用的进程地址空间。

另一方面,您可能拥有一个程序,该程序具有单个线程,该线程具有消耗大量堆栈空间的深度调用堆栈。在这种情况下,您可能会保留超过默认的1MB。

但是,除非你有充分的理由不这样做,否则最好坚持使用默认的堆栈大小。

答案 1 :(得分:1)

堆栈大小只是在创建多个线程的能力和其中一个线程中stack overflow的可能性之间进行权衡。

堆栈大小越多,可以创建的线程数越少,堆栈溢出的可能性就越小。只有在要创建多个线程时才应该担心堆栈大小(您必须降低堆栈大小,但要记住堆栈溢出)。否则默认值就足够了。

答案 2 :(得分:0)

  

但如果我指定32个字节会发生什么?

我还没有阅读Windows文档,但如果Windows允许(仅指定32个字节),则很可能会出现堆栈溢出。根据他们的文档,值以任何形式四舍五入到页面大小,因此实际上堆栈大小至少是页面的大小。创建的线程假定存在足够的"堆栈空间"它用于(用于分配自动变量,存储功能地址等),并根据它的需要分配空间。当没有足够的堆栈空间时,堆栈分配器可能会使用无效的内存,覆盖其他地方使用的内存。

  

线程中的堆栈大小定义了什么?

它定义了将为该线程的堆栈分配多少内存。

对线程调用堆栈的确切内容有一个很好的描述here