线程内存布局 [英] Thread(s) Memory Layout

查看:117
本文介绍了线程内存布局的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我了解进程内存布局的外观(代码,数据,堆,堆栈).

但是,我不明白带有多个线程的程序的内存布局到底是什么样子.

毕竟,该进程只有一个堆栈,所以我假设所有线程都以某种方式共享同一堆栈. 但这似乎是不对的,因为每个线程都有自己的堆栈,而且也不保证线程按照被调用的顺序执行,因此,将它们一个一地放在进程堆栈上对我来说没有多大意义.

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

线程的内存布局

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

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

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

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

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

非常感谢.

解决方案

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

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

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

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

I understand how a process memory layout looks like (Code, Data, Heap, Stack).

I do not understand, however, what exactly does a memory layout look like of a program with multiple threads.

After all, there is one stack for the process, so I would assume that all threads are sharing the same stack somehow.. But this does not seem right because every thread has its own stack, and threads are not guranteed to execute in the order they were called, so putting them one by one onto the process stack does not make a lot of sense to me.

I came across this picture on the net:

Threads memory layout

It appears here that every thread has its own stack, which makes sense, and also its own kernel stack.

Does that mean that I have (using the picture) 3 "processes" ? (Let's say that a process address space is 4GB, then 3 threads would be 12GB? I think not..)

I want to understand where each of the thread's stack sit in the memory.

I know all threads share Data & Code segments, so I would assume that either the Heap will contain the thread's stacks, or they will sit in Kernel space..

I would really like to know what happens..

Many appreciations.

解决方案

First of all, lets clearly separate both definitions. The process actually is a container of isolation which can hold system resources (like sockets, mutexes, etc.) and in which environment threads can execute. The process has no stack and does not receive CPU time (not schedulable). In contrast, the thread is a unit of scheduling performed by OS kernel. Thread periodically receives quant of CPU time to make progress and has a stack to store temporal data (local variables and return addresses).

The first note: virtual address space is a core part of the process abstraction. Each process has its own virtual address space and each virtual address space belongs only to one process. The second note: All threads running in the process share all resources of the process. Hence, all threads of the same process share the same address space. Every thread is able to access every byte of memory which another thread can access. One thread even can access local variables on the stack of another thread.

In the old UNIX, there was only one abstraction -- a process. But from the modern point of view, we could say that UNIX was stuck to 1-to-1 model (every process has one and only one thread). Due to this 1-to-1 model, UNIX was able to fix stack location in memory. Currently adopted 1-to-N model (multiple threads per single process) assumes that there is no such fixed stack location. Instead, OS kernel is responsible for locating space for the stack when it is requested to create the thread and for releasing of that space on thread termination. Furthermore, kernel even can reject the thread creation request if it will fail on the lookup of a free chunk of process virtual address space.

To maintain an illusion of uninterruptable thread execution. Kernel tracks for each thread its instruction and stack pointers. When kernel loads the thread on CPU (gives CPU time to the thread to execute) it loads special CPU registers with instruction and stack pointers maintained by the kernel for this particular thread. And when kernel unloads the thread from CPU it stores these pointers in the kernel memory. In such a way, the kernel creates an illusion that each thread has its own separate stack because thread itself does not need to deal with this stack pointer manipulations. In fact, we can say that each thread has its own part of address space logically assigned to him, but physically accessible to everybody in the process, but each thread has its own private stack pointer.

这篇关于线程内存布局的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆