![]() |
1
146
你说得很对,但线程共享所有段 除了 堆栈。线程有独立的调用堆栈,但是其他线程堆栈中的内存仍然可以访问,从理论上讲,您可以在其他线程的本地堆栈帧中保存指向内存的指针(尽管您可能应该找到更好的位置来放置内存!). |
![]() |
2
48
从 Wikipedia (我认为这会给面试官一个很好的回答:p)
|
![]() |
3
38
需要指出的是,这个问题实际上有两个方面——理论方面和实现方面。 首先,让我们看看理论方面。您需要从概念上理解流程是什么,以理解流程和线程之间的区别以及它们之间共享的内容。 我们有以下部分 2.2.2经典螺纹模型 在里面 Modern Operating Systems 3e 塔嫩鲍姆:
他继续说:
下一步,他提供了下表:
上面是线程工作所需的。正如其他人指出的那样,段之类的东西依赖于操作系统的实现细节。 |
![]() |
4
26
告诉面试官这完全取决于操作系统的实现。 以Windows x86为例。只有 二 段[1],代码和数据。它们都映射到整个2GB(线性,用户)地址空间。基极=0,极限=2GB。他们本来可以做一个,但x86不允许读/写和执行一个段。所以他们做了两个,并将cs设置为指向代码描述符,而其余的(ds、es、ss等)则指向另一个[2]。但两者都指向相同的东西! 面试你的人有一个隐藏的假设,他/她没有陈述,这是一个愚蠢的伎俩。 所以关于
这些片段与问题无关,至少在Windows上是这样。线程共享整个地址空间。只有一个堆栈段ss,它指向与ds、es和cs所做的完全相同的东西[2]。即。 整个该死的用户空间 .0-2GB。当然,这并不意味着线程只有一个堆栈。当然,每个都有自己的堆栈,但x86段不用于此目的。 也许尼克斯做了一些不同的事情。谁知道呢。这个问题所基于的前提被打破了。
|
![]() |
5
17
通常,螺纹被称为轻量加工。如果我们将内存分为三个部分,那么它将是:代码、数据和堆栈。 每个进程都有自己的代码、数据和堆栈部分,因此上下文切换时间有点高。为了减少上下文切换时间,人们提出了线程的概念,它与其他线程/进程共享数据和代码段,并且有自己的堆栈段。 |
![]() |
6
16
进程具有代码、数据、堆和堆栈段。现在,一个或多个线程的指令指针(IP)指向进程的代码段。数据段和堆段由所有线程共享。那么栈区呢?什么是堆叠区域?它是由进程创建的一个区域,只供线程使用…因为堆栈的使用速度比堆等快得多。进程的堆栈区域被划分为多个线程,即如果有3个线程,则将进程的堆栈区域划分为3个部分,并将每个部分分配给3个线程。换句话说,当我们说每个线程都有自己的堆栈时,这个堆栈实际上是分配给每个线程的进程堆栈区域的一部分。当一个线程完成其执行时,该线程的堆栈将由进程回收。事实上,不仅一个进程的堆栈被划分为多个线程,而且一个线程使用的所有寄存器集(如sp、pc和state寄存器)都是该进程的寄存器。 因此,在共享方面,代码、数据和堆区域是共享的,而堆栈区域只是在线程之间划分的。 |
![]() |
7
12
线程共享代码、数据段和堆,但不共享堆栈。 |
![]() |
8
5
线程共享数据和代码,而进程不共享。堆栈不能为两者共享。
进程还可以共享内存,更精确地说是代码,例如
Process Thread Stack private private Data private shared Code private1 shared2 一 代码是 逻辑上 私有,但出于性能原因可能共享。 二 我不是百分之百确定。 |
![]() |
9
4
线程共享 一切 〔1〕。整个过程有一个地址空间。 每个线程都有自己的堆栈和寄存器,但是所有线程的堆栈都在共享地址空间中可见。 如果一个线程在其堆栈上分配某个对象,并将地址发送给另一个线程,那么它们对该对象的访问都是相同的。 实际上,我注意到了一个更广泛的问题:我认为你混淆了这个词的两个用法 段 . 可执行文件(例如,elf)的文件格式中有不同的部分,这些部分可以称为段,其中包含编译代码(文本)、初始化数据、链接器符号、调试信息等。这里没有堆或堆栈段,因为这些段只是运行时构造。 这些二进制文件段可以单独映射到进程地址空间,具有不同的权限(例如,代码/文本的只读可执行文件,初始化数据的写时复制不可执行文件)。 此地址空间的区域按约定(由语言运行库强制)用于不同的目的,如堆分配和线程堆栈。不过,这些都只是内存,除非在虚拟8086模式下运行,否则可能不会被分段。每个线程的堆栈是在线程创建时分配的一块内存,当前堆栈顶部地址存储在堆栈指针寄存器中,每个线程都将自己的堆栈指针与其其他寄存器一起保存。 [1]好的,我知道:信号屏蔽、TSS/TSD等。但是地址空间,包括其所有映射的程序段,仍然是共享的。 |
![]() |
10
2
在x86框架中,可以划分任意多个段(最多2^16-1)。asm指令segment/ends允许这样做,运算符seg和offset允许初始化段寄存器。cs:ip通常由加载程序初始化,但是对于ds、es、ss,应用程序负责初始化。 许多环境允许所谓的“简化段定义”,如.code,.data,.bss,.stack等,并且,根据“内存模型”(小、大、紧凑等),加载程序会相应地初始化段寄存器。通常.data,.bss,.stack和其他常见的段(我从20年来就没有这样做了,所以我不记得全部)被分组在一个组中-这就是为什么ds,es和ss通常指向同一个区域,但这只是为了简化事情。 一般来说,所有段寄存器在运行时都可以有不同的值。 因此,访谈问题是正确的:线程之间共享的是代码、数据和堆栈中的哪一个。堆管理是另外一回事——它只是对操作系统的一系列调用。但是,如果你根本没有操作系统,比如在嵌入式系统中,你的代码中还能有新的/删除的操作系统呢? 我给年轻人的建议-读一些好的汇编编程书。在这方面,大学的课程似乎很差。 |
![]() |
11
1
线程共享堆(有关于线程特定堆的研究),但当前的实现共享堆。(当然还有代码) |
![]() |
12
0
在进程中,所有线程共享系统资源,如堆内存等,而线程有自己的堆栈。 所以您的ans应该是所有线程为一个进程共享的堆内存。 |
![]() |
13
0
摘录自: The Linux Programming Interface: A Linux and UNIX System Programming Handbook , Michael Kerrisk ,第619页 |
![]() |
Denis · 在C、linux中同步进程 1 年前 |
![]() |
ridhomblr · 如果DI>32767,VGA输出不显示 1 年前 |
![]() |
dmgzh · 如何根据所使用的系统更改变量值?(Python) 1 年前 |
|
gitm_248 · Ubuntu安装和关闭的问题:寻求解决问题的指导 1 年前 |
![]() |
Adriana · 尝试创建文件列表时出错 1 年前 |