进程和线程之间的技术区别是什么?

我感觉像“进程”这样的词被过度使用了,而且还有硬件和软件线程。像Erlang这样的语言中的轻量级进程怎么样?是否有明确的理由使用一个术语而不是另一个术语?


当前回答

来自嵌入式世界,我想补充一点,进程的概念只存在于具有MMU(内存管理单元)的“大型”处理器(台式CPU、ARM Cortex A-9)和支持使用MMU的操作系统(如Linux)中。对于小型/老式处理器和微控制器以及小型RTOS操作系统(实时操作系统),如freeRTOS,没有MMU支持,因此没有进程,只有线程。

线程可以访问彼此的内存,并且它们由OS以交错的方式调度,因此它们看起来是并行运行的(或者对于多核线程,它们实际上是并行运行)。

另一方面,进程则生活在由MMU提供和保护的私有虚拟内存沙盒中。这很方便,因为它可以:

防止错误进程导致整个系统崩溃。通过使其他流程数据不可见和无法访问。进程内的实际工作由一个或多个线程负责。

其他回答

http://lkml.iu.edu/hypermail/linux/kernel/9608/0191.html

莱纳斯·托瓦尔兹(torvalds@cs.helsinki.fi)1996年8月6日星期二12:47:31+0300(欧洲东部夏令时)邮件排序依据:[date][thread][subject][author]下一条消息:Bernd P.Ziller:“回复:get_hash_table中的错误”上一条消息:Linus Torvalds:“Re:I/O请求排序”1996年8月5日星期一,Peter P.Eiserloh写道:我们需要明确线程的概念。太多人了似乎混淆了线程和进程。以下讨论不反映linux的当前状态,而是试图保持高级别的讨论。不!没有理由认为“线程”和“进程”是独立实体。这是传统的做法,但我我个人认为这样想是一个重大错误。唯一的有理由认为这种方式是历史包袱。线程和进程实际上只是一件事:试图人为地区分不同的案例只是自我限制。一个“执行环境”,这里称为COE,只是一个企业集团该状态包括CPU等状态(寄存器等)、MMU状态(页面映射)、权限状态(uid、gid)和各种“通信状态”(打开文件、信号处理器等)。传统上,“线程”和“进程”主要是指线程具有CPU状态(+可能一些其他最小状态),而所有其他上下文都来自过程然而,这只是一种划分COE总状态的方法,没有任何东西表明这是正确的方法。限制自己对那种形象来说简直是愚蠢至极。Linux对此的思考方式(以及我希望的工作方式)是没有所谓的“进程”或“线程”。有只有整个COE(Linux称为“任务”)。不同的COE可以彼此共享部分上下文共享是传统的“线程”/“进程”设置,但应该真正被视为仅仅是一个子集(它是一个重要的子集,但是这种重要性不是来自设计,而是来自标准:我们显然希望在Linux上运行符合标准的线程程序也是)。简而言之:不要围绕线程/进程的思维方式进行设计。这个内核应该围绕COE的思维方式进行设计,然后pthread库可以将有限的pthread接口导出给用户他们想用这种方式来看待COE。作为一个例子,当你认为COE是与线程/进程相反:您可以执行外部“cd”程序,这在UNIX和/或进程/线程中传统上是不可能的(愚蠢的例子,但想法你可以拥有这些类型的“模块”传统的UNIX/threads设置)。执行以下操作:克隆(clone_VM|clone_FS);child:execve(“外部cd”);/*“execve()”将解除VM的关联,因此使用CLONE_VM是为了更快地进行克隆*/您可以自然地执行“vfork()”(它需要最少的内核支持,但这种支持完全符合CUA的思维方式):克隆(clone_VM);child:继续运行,最终执行()妈妈:等高管您可以执行外部“IO deamons”:克隆(clone_FILES);child:打开文件描述符等妈妈:用孩子打开的fd和vv。以上所有的工作都是因为您没有绑定到线程/进程思维方式。以web服务器为例,其中CGI脚本作为“执行线程”完成。你不能用传统线程,因为传统线程总是必须共享整个地址空间,所以你必须链接所有你曾经希望在web服务器本身(一个“线程”不能运行另一个可执行)。将此视为“执行上下文”问题任务现在可以选择执行外部程序(=将来自父级的地址空间)等,或者他们可以示例与父级共享除文件之外的所有内容描述符(这样子“线程”可以打开大量文件家长需要担心它们:当子“线程”退出,并且不会使用父级中的fd)。例如,设想一个线程化的“inetd”。你想要低开销fork+exec,所以用Linux的方式可以代替使用“fork()”您编写了一个多线程inetd,其中每个线程都是用仅CLONE_VM(共享地址空间,但不共享文件描述符等等)。然后,如果它是外部服务(rlogind,例如),或者可能是内部inetd服务之一(echo,timeofday)在这种情况下,它只是做它自己的事情,然后退出。你不能用“线程”/“进程”这样做。莱纳斯牌手表

首先,让我们看看理论方面。您需要从概念上理解什么是进程,才能理解进程和线程之间的区别以及它们之间的共享。

Tanenbaum在第2.2.2节现代操作系统的经典线程模型3e中介绍了以下内容:

流程模型基于两个独立的概念:资源分组和执行。有时将它们分开是有用的;这是线程进入的地方。。。。

他继续说道:

看待过程的一种方式是将相关资源分组在一起。进程具有地址空间包含程序文本和数据以及其他资源。这些资源可以包括打开的文件、子进程、挂起的警报等,信号处理器、会计信息等。通过将它们以流程的形式结合在一起,可以更容易地管理它们。进程的另一个概念是执行线程,通常缩短为仅螺纹。线程有一个程序计数器跟踪下一步要执行的指令。它有寄存器保持其当前工作变量。它有一个堆栈,其中包含执行历史,每个过程调用一帧,但未调用但从返回。尽管线程必须在某些进程中执行线程及其进程是不同的概念分别地。流程用于将资源分组在一起;螺纹是计划在CPU上执行的实体。

接下来,他提供了下表:

Per process items             | Per thread items
------------------------------|-----------------
Address space                 | Program counter
Global variables              | Registers
Open files                    | Stack
Child processes               | State
Pending alarms                |
Signals and signal handlers   |
Accounting information        |

让我们来处理硬件多线程问题。传统上,CPU将支持单个执行线程,通过单个程序计数器(PC)和一组寄存器来维护线程的状态。但当缓存未命中时会发生什么?从主内存中获取数据需要很长时间,而当这发生时,CPU只是闲置在那里。所以有人想到了基本上有两组线程状态(PC+寄存器),这样另一个线程(可能在同一个进程中,也可能在不同的进程中)就可以在其他线程等待主内存时完成工作。这个概念有多种名称和实现,例如超线程和同时多线程(简称SMT)。

现在让我们看看软件方面。基本上有三种方法可以在软件端实现线程。

用户空间线程内核进程两者的结合

实现线程所需要的是保存CPU状态和维护多个堆栈的能力,这在许多情况下可以在用户空间中完成。用户空间线程的优点是超快速的线程切换,因为您不必陷入内核,也不必按照自己喜欢的方式调度线程。最大的缺点是无法阻止I/O(这会阻止整个进程及其所有用户线程),这是我们首先使用线程的主要原因之一。在许多情况下,使用线程阻止I/O大大简化了程序设计。

除了将所有调度问题留给操作系统之外,内核线程还具有能够使用阻塞I/O的优点。但每个线程切换都需要捕获内核,这可能会相对较慢。然而,如果由于I/O阻塞而切换线程,这实际上不是问题,因为I/O操作可能已经将您困在内核中。

另一种方法是将两者结合起来,多个内核线程每个都有多个用户线程。

因此,回到术语问题,您可以看到流程和执行线程是两个不同的概念,您选择使用哪个术语取决于您所谈论的内容。关于“轻量级过程”这一术语,我个人看不出其中的意义,因为它并没有像“执行线程”这一词那样真正传达出正在发生的事情。

从面试官的角度来看,我基本上只想听到3件主要事情,除了像流程这样的显而易见的事情外,还有多个线程:

线程共享相同的内存空间,这意味着一个线程可以从其他线程的内存访问内存。进程通常不能。资源。资源(内存、句柄、套接字等)在进程终止时释放,而不是线程终止时释放。安全进程具有固定的安全令牌。另一方面,线程可以模拟不同的用户/令牌。

如果你想要更多,Scott Langham的回应几乎涵盖了所有内容。所有这些都是从操作系统的角度来看的。不同的语言可以实现不同的概念,如任务、轻线程等等,但它们只是使用线程(Windows上的光纤)的方式。没有硬件和软件线程。存在硬件和软件异常和中断,或者用户模式和内核线程。

我从知识探索中复制了这些信息!博客:

流程:程序的执行实例称为进程。一些操作系统使用术语“任务”来指代正在执行的程序。进程总是存储在也称为主存储器或随机存取存储器的主存储器中。因此,流程被称为活动实体。如果重新启动机器,它将消失。多个进程可以与同一程序相关联。在多处理器系统上,可以并行执行多个进程。在单处理器系统上,虽然无法实现真正的并行性,但应用了进程调度算法,处理器计划每次执行一个过程,产生一种错觉并发性。示例:执行“计算器”程序的多个实例。每个实例都称为一个过程。线程:线程是进程的子集。它被称为“轻量级进程”,因为它类似于真实进程,但在进程的上下文中执行并共享内核分配给进程的相同资源。通常,一个进程只有一个控制线程——一次执行一组机器指令。进程也可以由并发执行指令的多个执行线程组成。多个控制线程可以利用多处理器系统上可能的真正并行性。在单处理器系统上,应用线程调度算法,并调度处理器每次运行一个线程。进程中运行的所有线程共享相同的地址空间、文件描述符、堆栈和其他与进程相关的属性。由于进程的线程共享相同的内存,同步进程内共享数据的访问将获得前所未有的效果重要性

将流程视为一个所有权单位或任务所需的资源。进程可以具有内存空间、特定输入/输出、特定文件和优先级等资源。

线程是一个可调度的执行单元,或者简单地说是一系列指令的进程