我了解进程内存布局的样子(代码、数据、堆、堆栈)。
但是,我不明白具有多个线程的程序的内存布局究竟是什么样的。
毕竟,该进程有一个堆栈,所以我假设所有线程都以某种方式共享相同的堆栈。
但这似乎不对,因为每个线程都有自己的堆栈,并且不能保证线程按照调用的顺序执行,因此将它们一一放入进程堆栈对我来说没有多大意义。
我在网上看到了这张图:
线程内存布局 https://i.stack.imgur.com/Ytv2X.gif
这里看来每个线程都有自己的堆栈,这是有道理的,而且还有自己的内核堆栈。
这是否意味着我(使用图片)有 3 个“进程”? (假设一个进程地址空间是 4GB,那么 3 个线程就是 12GB?我认为不是..)
我想了解每个线程的堆栈位于内存中的位置。
我知道所有线程共享数据和代码段,因此我假设堆将包含线程的堆栈,或者它们将位于内核空间中。
我真的很想知道会发生什么..
许多赞赏。
首先,让我们清楚地区分这两个定义。进程实际上是一个隔离容器,可以容纳系统资源(如套接字、互斥体等),并且线程可以在该环境中执行。该进程没有堆栈,并且不接收CPU时间(不可调度)。相反,线程是操作系统内核执行调度的单位。线程定期接收一定量的 CPU 时间来取得进展,并有一个堆栈来存储临时数据(局部变量和返回地址)。
第一个说明:虚拟地址空间是进程抽象的核心部分。每个进程都有自己的虚拟地址空间,每个虚拟地址空间只属于一个进程。
第二个注意点:进程中运行的所有线程共享进程的所有资源。因此,同一进程的所有线程共享相同的地址空间。每个线程都能够访问另一个线程可以访问的每个内存字节。一个线程甚至可以访问另一线程堆栈上的局部变量。
在旧的 UNIX 中,只有一个抽象——进程。但从现代的角度来看,我们可以说 UNIX 一直坚持一对一的模型(每个进程只有一个线程)。由于这种一对一的模型,UNIX 能够修复内存中的堆栈位置。目前采用的 1 对 N 模型(每个进程多个线程)假设不存在这样的固定堆栈位置。相反,操作系统内核负责在请求创建线程时为堆栈定位空间,并在线程终止时释放该空间。此外,如果在查找进程虚拟地址空间的空闲块时失败,内核甚至可以拒绝线程创建请求。
保持线程执行不可中断的假象。内核跟踪每个线程的指令和堆栈指针。当内核将线程加载到 CPU 上(为线程提供 CPU 时间来执行)时,它会加载特殊的 CPU 寄存器,其中包含内核为该特定线程维护的指令和堆栈指针。当内核从 CPU 卸载线程时,它将这些指针存储在内核内存中。通过这种方式,内核会产生一种错觉,即每个线程都有自己单独的堆栈,因为线程本身不需要处理此堆栈指针操作。事实上,我们可以说每个线程都有自己的逻辑上分配给他的部分地址空间,但物理上可供进程中的每个人访问,但每个线程都有自己的私有堆栈指针。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)