最近,我在一次采访中被问到一个问题:进程和线程有什么区别?真的,我不知道答案。我想了一会儿,给出了一个非常奇怪的答案。
线程共享相同的内存,而进程不共享。回答完这个问题后,面试官对我邪恶地笑了笑,然后接连问了我几个问题:
问:你知道节目分成哪些部分吗?
我的答案是:是的(认为这很简单)堆栈,数据,代码,堆
问:那么,告诉我:线程共享哪些片段?
我无法回答这个问题,最后只能把它们都说了出来。
请问,谁能就进程和线程之间的区别给出正确的、令人印象深刻的答案?
最近,我在一次采访中被问到一个问题:进程和线程有什么区别?真的,我不知道答案。我想了一会儿,给出了一个非常奇怪的答案。
线程共享相同的内存,而进程不共享。回答完这个问题后,面试官对我邪恶地笑了笑,然后接连问了我几个问题:
问:你知道节目分成哪些部分吗?
我的答案是:是的(认为这很简单)堆栈,数据,代码,堆
问:那么,告诉我:线程共享哪些片段?
我无法回答这个问题,最后只能把它们都说了出来。
请问,谁能就进程和线程之间的区别给出正确的、令人印象深刻的答案?
当前回答
告诉面试官这完全取决于操作系统的实现。
以Windows x86为例。只有两个段[1],代码和数据。它们都被映射到整个2GB(线性,用户)地址空间。基础= 0,限制= 2 gb。他们本来可以做一个,但x86不允许一个段同时读/写和执行。所以他们做了两个,并设置CS指向代码描述符,其余(DS, ES, SS等)指向另一个[2]。但两者都指向同样的东西!
面试你的人做了一个隐藏的假设,他/她没有说出来,这是一个愚蠢的伎俩。
所以关于
问:告诉我是哪个线段 分享吗?
细分市场与问题无关,至少在Windows上是这样。线程共享整个地址空间。只有一个堆栈段SS,它指向DS ES CS做的完全一样的东西[2]。比如整个用户空间。0-2GB。当然,这并不意味着线程只有一个堆栈。当然,每个都有自己的堆栈,但x86段并不用于此目的。
也许*nix做一些不同的事情。谁知道呢。这个问题的前提被打破了。
至少对于用户空间是这样的。 从ntsd记事本:cs=001b ss=0023 ds=0023 es=0023
其他回答
通常,线程被称为轻量级进程。如果我们把内存分成三个部分,那么它将是:代码,数据和堆栈。 每个进程都有自己的代码、数据和堆栈部分,由于这种上下文切换时间有点高。为了减少上下文切换的时间,人们提出了线程的概念,它与其他线程/进程共享数据和代码段,并拥有自己的堆栈段。
来自维基百科(我认为这对面试官来说是个很好的回答:P)
Threads differ from traditional multitasking operating system processes in that: processes are typically independent, while threads exist as subsets of a process processes carry considerable state information, whereas multiple threads within a process share state as well as memory and other resources processes have separate address spaces, whereas threads share their address space processes interact only through system-provided inter-process communication mechanisms. Context switching between threads in the same process is typically faster than context switching between processes.
线程共享数据和代码,而进程不共享。栈不是为两者共享的。
进程也可以共享内存,更精确的代码,例如Fork()之后,但这是一个实现细节和(操作系统)优化。由多个进程共享的代码将(希望)在第一次写入代码时复制—这被称为写时复制。我不确定线程代码的确切语义,但我假设是共享代码。
Process Thread Stack private private Data private shared Code private1 shared2
代码在逻辑上是私有的,但出于性能原因可能会被共享。 我不能百分之百肯定。
在进程中,所有线程共享系统资源,如堆内存等,而线程有自己的堆栈
所以你的ans应该是一个进程中所有线程共享的堆内存。
线程共享所有内容[1]。整个进程只有一个地址空间。
每个线程都有自己的堆栈和寄存器,但所有线程的堆栈都在共享地址空间中可见。
如果一个线程在它的堆栈上分配了某个对象,并将该地址发送给另一个线程,它们对该对象的访问权是相等的。
实际上,我刚刚注意到一个更广泛的问题:我认为你混淆了segment这个词的两种用法。
可执行文件(如ELF)的文件格式有不同的部分,可以称为段,包含编译的代码(文本)、初始化的数据、链接器符号、调试信息等。这里没有堆段或堆栈段,因为它们是仅运行时结构。
这些二进制文件段可以分别映射到进程地址空间,具有不同的权限(例如,对于代码/文本,只读可执行;对于初始化的数据,写时复制不可执行)。
根据约定(由语言运行库强制执行),这个地址空间的区域用于不同的目的,如堆分配和线程堆栈。不过,这些都只是内存,并且可能没有分段,除非您在虚拟8086模式下运行。每个线程的堆栈是在线程创建时分配的内存块,当前堆栈顶部地址存储在堆栈指针寄存器中,每个线程保留自己的堆栈指针和其他寄存器。
好的,我知道:信号掩码,TSS/TSD等。地址空间,包括它所有映射的程序段,仍然是共享的。