操作系统如何为每个线程实现或维护堆栈?

问题描述 投票:0回答:3

关于线程是否拥有自己的堆栈,存在各种问题。然而,我无法理解操作系统如何实现或者操作系统通常如何实现每个线程一个堆栈。在操作系统书籍中,程序的内存布局如下所示:

Memory Layout

注意,可以将其视为连续的内存块(虚拟内存)。我想象虚拟内存空间的某些部分被划分在线程的堆栈之间。这让我想到了这个问题的第二部分:一个流行的技术面试问题涉及尝试使用单个数组实现 3 个堆栈。这个问题是不是和解决线程栈的实现有直接关系呢?

我这样总结我的问题:

  1. 现代操作系统(例如 Linux)如何为不同线程的堆栈划分内存空间?
  2. “3 个堆栈使用 1 个数组”是否与上述问题直接相关或者是上述问题的答案?

PS:也许用图像来解释如何为不同的线程堆栈划分内存是最好的解释。

multithreading operating-system stack
3个回答
8
投票

上面显示的图片在 Windows 和 Linux 上都完全“过时”了。各个分配位于什么地址并不重要。虚拟地址空间在 32 位上很大,在 64 位上也很大。操作系统只需要在某处中切出一些块并将其分发出去。

每个堆栈都是一个独立的虚拟内存分配

,可以放置在任意位置。值得注意的是,堆栈通常“大小有限”。操作系统保留一定的最大大小(例如 1MB 或 8MB)。堆栈不能超过该大小。上图(已过时)对此提出了不同的建议。堆栈确实向下增长,但是当固定空间耗尽时,就会触发堆栈溢出。这在实践中不是一个问题。事实上,超过合理的堆栈大小被认为是一个错误。 二进制图像(上图:文本、初始化数据和 bss)也可以放置在任何地方。它们的尺寸也是固定的。

由多个段组成。只需添加更多段即可任意增长。堆由用户模式库管理。内核不知道这一点。内核所做的就是在随意选择的位置提供虚拟内存块。

1)线程的堆栈只是虚拟内存中的一个连续块。它的最大尺寸是固定的。它可能看起来像这样:


3
投票

2)我不认为它与这个问题直接相关,因为在创建线程时线程的堆栈大小限制是已知的,但是在关于“3个堆栈使用1个数组”的问题中,对3个堆栈中每一个的大小一无所知。

补充 usr 的答案,这是使用虚拟内存的堆栈视图:


© www.soinside.com 2019 - 2024. All rights reserved.