【问题标题】:How does the Operating System determine how much stack space should be allotted to each thread?操作系统如何确定应该为每个线程分配多少堆栈空间?
【发布时间】:2014-03-29 14:52:05
【问题描述】:

操作系统如何确定在底层进程的地址空间中将给每个线程多少堆栈空间?

如果一个线程使用了最初分配给它的所有堆栈空间,并且同一进程的其他线程存在大量未充分利用的空间,该怎么办? 我知道,堆栈和堆的同类问题可以通过它们向相反方向增长来解决。

操作系统是否在内存中的其他地方为线程分配了更多空间,还是会导致堆栈溢出?

【问题讨论】:

  • 当线程耗尽其堆栈时会发生什么?答案在您的问题之上。
  • 但是如果进程的地址空间中有很多其他线程未充分利用的空间,是否仍然会导致堆栈溢出?
  • 是的。每个线程的堆栈都是独立的,并且独立于其他线程堆栈。将它们混合在一起通常是一个非常糟糕的主意。
  • 在虚拟内存的情况下,这是一个很难回答的问题。线程堆栈通常是可交换的。这取决于你所说的“分配给它”是什么意思。
  • 通常你有虚拟内存和物理内存。创建线程时会为堆栈分配一块虚拟内存。物理内存按需分配给该虚拟内存。一旦分配了物理内存,就可以将其换出。如果虚拟地址空间有空间,一些系统可以在需要时自动增加堆栈。

标签: multithreading memory memory-management concurrency operating-system


【解决方案1】:

这不是由操作系统决定的,这是程序员的工作。以Windows为例,操作系统启动的first线程的栈大小在可执行文件头中指定。 IMAGE_OPTIONAL_HEADER.SizeOfStackReserve 设置大小。这将责任转嫁给生成标头的任何工具,例如链接器,您可以使用其/STACK option 来设置大小。

大多数构建工具会使用一个合理的默认大小,1 MB 作为保留大小是很常见的,4096(一页)作为初始提交大小。或者不那么合理的默认值,.NET 程序臭名昭著地预先提交了整个堆栈空间。

这也需要在启动线程时指定,像CreateThread这样的winapi函数需要一个参数来设置大小。可以使用默认值,如果您指定 0,则操作系统使用 EXE 标头中指定的大小。这很常见,实际大小很少是关键的,因为大多数程序都会严重超大堆栈。远离灾难很重要。请注意,在按需分页的操作系统上,超大堆栈不会花费任何成本,您只需为使用的内容付费。

在许多情况下,堆栈空间不足是一个不可恢复的错误,处理器无法再进行调用。此网站名称的原因。周围有其他线程没有消耗它们的整个堆栈是无关紧要的,切换堆栈通常不起作用。程序使用指向堆栈空间的指针,你找不到它们来更新值。

【讨论】:

  • 这是否意味着如果一个线程使用了程序员希望它拥有的默认堆栈空间,并且超出该空间,下一个线程的堆栈空间开始启动,程序会给我一个堆栈溢出,或者在对虚拟内存映射进行更改后,是否可以将该堆栈从内存中的当前位置换出并存储在内存中可用空间的其他位置?
  • 问和回答。您确实需要停止假设“交换”可以工作。它不能。学习 C 语言是理解机器的好方法。
猜你喜欢
  • 2014-10-07
  • 2014-05-27
  • 2023-03-23
  • 2013-05-21
  • 2011-05-15
  • 2014-06-29
  • 2020-09-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多