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

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

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

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

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

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

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


当前回答

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

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

其他回答

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应该是一个进程中所有线程共享的堆内存。

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

线程共享所有内容[1]。整个进程只有一个地址空间。

每个线程都有自己的堆栈和寄存器,但所有线程的堆栈都在共享地址空间中可见。

如果一个线程在它的堆栈上分配了某个对象,并将该地址发送给另一个线程,它们对该对象的访问权是相等的。


实际上,我刚刚注意到一个更广泛的问题:我认为你混淆了segment这个词的两种用法。

可执行文件(如ELF)的文件格式有不同的部分,可以称为段,包含编译的代码(文本)、初始化的数据、链接器符号、调试信息等。这里没有堆段或堆栈段,因为它们是仅运行时结构。

这些二进制文件段可以分别映射到进程地址空间,具有不同的权限(例如,对于代码/文本,只读可执行;对于初始化的数据,写时复制不可执行)。

根据约定(由语言运行库强制执行),这个地址空间的区域用于不同的目的,如堆分配和线程堆栈。不过,这些都只是内存,并且可能没有分段,除非您在虚拟8086模式下运行。每个线程的堆栈是在线程创建时分配的内存块,当前堆栈顶部地址存储在堆栈指针寄存器中,每个线程保留自己的堆栈指针和其他寄存器。


好的,我知道:信号掩码,TSS/TSD等。地址空间,包括它所有映射的程序段,仍然是共享的。