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

7
在SO上有关于线程是否拥有自己的堆栈的各种问题。然而,我不明白操作系统如何实现或者通常如何实现每个线程一个堆栈。在操作系统书籍中,程序的内存布局如下所示:
Memory Layout
请注意,它可以被视为一块连续的内存块(虚拟内存)。我会想象虚拟内存空间的一部分被划分给线程的堆栈。这就引出了这个问题的第二部分:一个流行的技术面试问题涉及尝试使用一个数组来实现3个堆栈。这个问题直接相关于解决线程堆栈的实现吗?
我总结我的问题如下:
  1. 现代操作系统(例如Linux)如何划分不同线程的堆栈的内存空间?
  2. “使用1个数组实现3个堆栈”与上述问题直接相关还是答案?
附注:也许使用图像来解释不同线程堆栈的内存如何划分最好。
2个回答

8
上面展示的图片在Windows和Linux上都已经过时了。个别分配所在的地址并不重要。32位系统的虚拟地址空间很大,64位系统的虚拟地址空间更加广阔。操作系统只需要从中划出一部分空间,并将其分配出去。
每个堆栈都是独立的虚拟内存分配,可以放置在任意位置。需要注意的是,堆栈通常是有限大小的。操作系统预留了一定的最大大小(如1MB或8MB)。堆栈不能超过该大小。这与上面那张(过时的)图片所示有所不同。堆栈确实向下增长,但当固定空间用完时,就会触发堆栈溢出。实际上,超过合理的堆栈大小被认为是一个 bug,因此这并不是一个问题。
二进制映像(上面的文本、初始化数据和bss)也可以随意放置。它们的大小也是固定的。
堆由多个段组成。它可以通过添加更多的段来任意增长。堆由用户模式库管理,内核并不知道它的存在。内核所做的所有工作就是在任意选择的位置提供虚拟内存块。

哇,是的,它变得非常简单了。使用虚拟内存的另一个好处。=) - digvijay91

3

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

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接