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

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

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

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

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

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

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


当前回答

Besides global memory, threads also share a number of other attributes (i.e., these attributes are global to a process, rather than specific to a thread). These attributes include the following: process ID and parent process ID; process group ID and session ID; controlling terminal; process credentials (user and group IDs); open file descriptors; record locks created using fcntl(); signal dispositions; file system–related information: umask, current working directory, and root directory; interval timers (setitimer()) and POSIX timers (timer_create()); System V semaphore undo (semadj) values (Section 47.8); resource limits; CPU time consumed (as returned by times()); resources consumed (as returned by getrusage()); and nice value (set by setpriority() and nice()). Among the attributes that are distinct for each thread are the following: thread ID (Section 29.5); signal mask; thread-specific data (Section 31.3); alternate signal stack (sigaltstack()); the errno variable; floating-point environment (see fenv(3)); realtime scheduling policy and priority (Sections 35.2 and 35.3); CPU affinity (Linux-specific, described in Section 35.4); capabilities (Linux-specific, described in Chapter 39); and stack (local variables and function call linkage information).

摘自:《Linux编程接口:Linux和UNIX系统编程手册》,Michael Kerrisk,第619页

其他回答

Besides global memory, threads also share a number of other attributes (i.e., these attributes are global to a process, rather than specific to a thread). These attributes include the following: process ID and parent process ID; process group ID and session ID; controlling terminal; process credentials (user and group IDs); open file descriptors; record locks created using fcntl(); signal dispositions; file system–related information: umask, current working directory, and root directory; interval timers (setitimer()) and POSIX timers (timer_create()); System V semaphore undo (semadj) values (Section 47.8); resource limits; CPU time consumed (as returned by times()); resources consumed (as returned by getrusage()); and nice value (set by setpriority() and nice()). Among the attributes that are distinct for each thread are the following: thread ID (Section 29.5); signal mask; thread-specific data (Section 31.3); alternate signal stack (sigaltstack()); the errno variable; floating-point environment (see fenv(3)); realtime scheduling policy and priority (Sections 35.2 and 35.3); CPU affinity (Linux-specific, described in Section 35.4); capabilities (Linux-specific, described in Chapter 39); and stack (local variables and function call linkage information).

摘自:《Linux编程接口:Linux和UNIX系统编程手册》,Michael Kerrisk,第619页

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

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

在进程中,所有线程共享系统资源,如堆内存等,而线程有自己的堆栈

所以你的ans应该是一个进程中所有线程共享的堆内存。

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.