线程内存布局

Tal*_*Tal 5 memory layout multithreading process

我理解进程内存布局的样子(代码,数据,堆,堆栈).

但是,我不明白,具有多个线程的程序的内存布局究竟是什么样子.

毕竟,这个进程有一个堆栈,所以我假设所有线程都以某种方式共享相同的堆栈.但这似乎不正确,因为每个线程都有自己的堆栈,并且不保证线程在命令中执行他们被调用了,所以把它们一个一个地放到进程堆栈上对我来说并没有多大意义.

我在网上看到了这张照片:

线程内存布局

在这里看来,每个线程都有自己的堆栈,这是有意义的,也是它自己的内核堆栈.

这是否意味着我(使用图片)3"进程"?(假设进程地址空间为4GB,那么3个线程将为12GB?我认为不是..)

我想了解每个线程堆栈在内存中的位置.

我知道所有线程共享数据和代码段,所以我假设Heap将包含线程的堆栈,或者它们将位于内核空间中.

我真的很想知道会发生什么......

很多赞赏.

Zar*_*trA 4

首先,让我们清楚地区分这两个定义。进程实际上是一个隔离容器,可以容纳系统资源(如套接字、互斥体等),并且线程可以在该环境中执行。该进程没有堆栈,并且不接收CPU时间(不可调度)。相反,线程是操作系统内核执行调度的单位。线程定期接收一定量的 CPU 时间来取得进展,并有一个堆栈来存储临时数据(局部变量和返回地址)。

第一个说明:虚拟地址空间是进程抽象的核心部分。每个进程都有自己的虚拟地址空间,每个虚拟地址空间只属于一个进程。第二个注意点:进程中运行的所有线程共享进程的所有资源。因此,同一进程的所有线程共享相同的地址空间。每个线程都能够访问另一个线程可以访问的每个内存字节。一个线程甚至可以访问另一线程堆栈上的局部变量。

在旧的 UNIX 中,只有一个抽象——进程。但从现代的角度来看,我们可以说 UNIX 一直坚持一对一的模型(每个进程只有一个线程)。由于这种一对一的模型,UNIX 能够修复内存中的堆栈位置。目前采用的 1 对 N 模型(每个进程多个线程)假设不存在这样的固定堆栈位​​置。相反,操作系统内核负责在请求创建线程时为堆栈定位空间,并在线程终止时释放该空间。此外,如果在查找进程虚拟地址空间的空闲块时失败,内核甚至可以拒绝线程创建请求。

保持线程执行不可中断的假象。内核跟踪每个线程的指令和堆栈指针。当内核将线程加载到 CPU 上(为线程提供 CPU 时间来执行)时,它会加载特殊的 CPU 寄存器,其中包含内核为该特定线程维护的指令和堆栈指针。当内核从 CPU 卸载线程时,它将这些指针存储在内核内存中。通过这种方式,内核会产生一种错觉,即每个线程都有自己单独的堆栈,因为线程本身不需要处理此堆栈指针操作。事实上,我们可以说每个线程都有自己的逻辑上分配给他的地址空间部分,但物理上可供进程中的每个人访问,但每个线程都有自己的私有堆栈指针。