最近,我在一次采访中被问到一个问题:进程和线程有什么区别?真的,我不知道答案。我想了一会儿,给出了一个非常奇怪的答案。

线程共享相同的内存,而进程不共享。回答完这个问题后,面试官对我邪恶地笑了笑,然后接连问了我几个问题:

问:你知道节目分成哪些部分吗?

我的答案是:是的(认为这很简单)堆栈,数据,代码,堆

问:那么,告诉我:线程共享哪些片段?

我无法回答这个问题,最后只能把它们都说了出来。

请问,谁能就进程和线程之间的区别给出正确的、令人印象深刻的答案?


当前回答

A process has code, data, heap and stack segments. Now, the Instruction Pointer (IP) of a thread OR threads points to the code segment of the process. The data and heap segments are shared by all the threads. Now what about the stack area? What is actually the stack area? Its an area created by the process just for its thread to use... because stacks can be used in a much faster way than heaps etc. The stack area of the process is divided among threads, i.e. if there are 3 threads, then the stack area of the process is divided into 3 parts and each is given to the 3 threads. In other words, when we say that each thread has its own stack, that stack is actually a part of the process stack area allocated to each thread. When a thread finishes its execution, the stack of the thread is reclaimed by the process. In fact, not only the stack of a process is divided among threads, but all the set of registers that a thread uses like SP, PC and state registers are the registers of the process. So when it comes to sharing, the code, data and heap areas are shared, while the stack area is just divided among threads.

其他回答

In an x86 framework, one can divide as many segments (up to 2^16-1). The ASM directives SEGMENT/ENDS allows this, and the operators SEG and OFFSET allows initialization of segment registers. CS:IP are usually initialized by the loader, but for DS, ES, SS the application is responsible with initialization. Many environments allow the so-called "simplified segment definitions" like .code, .data, .bss, .stack etc. and, depending also on the "memory model" (small, large, compact etc.) the loader initializes segment registers accordingly. Usually .data, .bss, .stack and other usual segments (I haven't done this since 20 years so I don't remember all) are grouped in one single group - that is why usually DS, ES and SS points to teh same area, but this is only to simplify things.

一般来说,所有段寄存器在运行时都可以有不同的值。 所以,面试的问题是正确的:CODE、DATA和STACK中的哪一个在线程之间共享。堆管理是另一回事——它只是对操作系统的一系列调用。但是如果你根本没有操作系统,比如在嵌入式系统中,你还能在你的代码中新建/删除吗?

我给年轻人的建议是——读一些好的汇编编程书。似乎大学的课程在这方面相当贫乏。

线程共享代码、数据段和堆,但不共享堆栈。

告诉面试官这完全取决于操作系统的实现。

以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

您说得很对,但是线程共享除堆栈之外的所有段。线程有独立的调用堆栈,但是其他线程堆栈中的内存仍然是可访问的,理论上你可以在其他线程的本地堆栈框架中保存内存指针(尽管你可能应该找到一个更好的地方来放置内存!)。

A process has code, data, heap and stack segments. Now, the Instruction Pointer (IP) of a thread OR threads points to the code segment of the process. The data and heap segments are shared by all the threads. Now what about the stack area? What is actually the stack area? Its an area created by the process just for its thread to use... because stacks can be used in a much faster way than heaps etc. The stack area of the process is divided among threads, i.e. if there are 3 threads, then the stack area of the process is divided into 3 parts and each is given to the 3 threads. In other words, when we say that each thread has its own stack, that stack is actually a part of the process stack area allocated to each thread. When a thread finishes its execution, the stack of the thread is reclaimed by the process. In fact, not only the stack of a process is divided among threads, but all the set of registers that a thread uses like SP, PC and state registers are the registers of the process. So when it comes to sharing, the code, data and heap areas are shared, while the stack area is just divided among threads.