进程和线程有什么区别?

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

我感觉像'过程'这个词被过度使用,也有硬件和软件线程。 像Erlang这样的语言中的轻量级过程如何? 是否有一个明确的理由使用一个术语?

进程和线程都是独立的执行序列。 典型的区别是,线程(同一进程)在共享内存空间中运行,而进程在单独的内存空间中运行。

我不确定你可能指的是什么“硬件”和“软件”线程。 线程是一个操作环境特性,而不是CPU特性(尽pipeCPU通常具有使线程高效的操作)。

Erlang使用术语“进程”,因为它不公开一个共享内存多进程编程模型。 调用它们“线程”意味着它们共享内存。

处理
每个进程提供执行程序所需的资源。 进程具有虚拟地址空间,可执行代码,系统对象的打开句柄,安全上下文,唯一进程标识符,环境variables,优先级类别,最小和最大工作集大小以及至less一个执行线程。 每个进程都使用单线程启动,通常称为主线程,但可以从其任何线程创build其他线程。

线
线程是一个进程中的一个实体,可以被调度执行。 进程的所有线程共享其虚拟地址空间和系统资源。 另外,每个线程都维护exception处理程序,调度优先级,线程本地存储,唯一的线程标识符以及系统将用于保存线程上下文直到它被调度的一组结构。 线程上下文包括线程进程的地址空间中线程的一组机器寄存器,内核堆栈,线程环境块和用户堆栈。 线程也可以有自己的安全上下文,可以用来模拟客户端。


在这里find这个MSDN:
关于进程和线程

Microsoft Windows支持抢先式多任务处理,这可以创build多个进程同时执行多个线程的效果。 在多处理器计算机上,系统可以同时执行与计算机上的处理器一样多的线程。

处理:

  • 程序的执行实例称为进程。
  • 一些操作系统使用术语“任务”来指代正在执行的程序。
  • 一个进程总是存储在主存储器中,也被称为主存储器或随机存取存储器。
  • 因此,一个过程被称为活动实体。 如果机器重新启动,它将消失。
  • 几个进程可能与一个相同的程序相关联。
  • 在多处理器系统上,可以并行执行多个进程。
  • 在单处理器系统中,尽pipe没有实现真正的并行性,但是应用了进程调度algorithm,并且处理器被安排一次一个地执行每个进程,产生并发的错觉。
  • 示例:执行“计算器”程序的多个实例。 每个实例都被称为一个进程。

线:

  • 线程是进程的一个子集。
  • 它被称为“轻量级进程”,因为它与真实进程相似,但在进程的上下文中执行,并共享内核分配给进程的相同资源。
  • 通常,一个进程只有一个控制线程 – 一次执行一组机器指令。
  • 一个进程也可以由多个执行线程并发执行指令组成。
  • 多个控制线程可以利用多处理器系统上的真正的并行性。
  • 在单处理器系统上,应用了线程调度algorithm,并且处理器被安排一次运行一个线程。
  • 在一个进程中运行的所有线程共享相同的地址空间,文件描述符,堆栈和其他进程相关的属性。
  • 由于一个进程的线程共享相同的内存,所以同步访问共享数据和进程是非常重要的。

我从知识探索中借鉴了上述信息 博客

首先,我们来看看理论方面。 你需要理解一个过程是从概念上理解一个过程和一个线程之间的区别以及它们之间共享的东西。

我们从2.2.2节Tanenbaum的现代操作系统3e中 的经典线程模型

stream程模型基于两个独立的概念:资源分组和执行。 有时分开它们是有用的。 这是线程进来….

他继续说道:

查看stream程的一种方式是将相关资源分组在一起。 一个进程有一个包含程序文本和数据的地址空间,以及其他资源。 这些资源可能包括打开的文件,subprocess,待处理的警报,信号处理程序,会计信息等等。 通过将它们以stream程的forms放在一起,可以更容易地进行pipe理。 一个进程拥有的另一个概念是一个执行的线程,通常缩短为只是线程。 线程有一个程序计数器,用于跟踪下一个要执行的指令。 它有寄存器,它保存当前的工作variables。 它有一个包含执行历史的堆栈,每个被调用的过程有一个框架,但还没有返回。 虽然线程必须在某个进程中执行,但线程及其进程是不同的概念,可以分开处理。 过程用于将资源组合在一起; 线程是计划在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 | 

我们来处理硬件multithreading问题。 通常情况下,一个CPU将支持一个执行线程,通过一个程序计数器和一组寄存器维持线程的状态。 但是如果有一个caching未命中会发生什么? 从主存储器中获取数据需要很长时间,在发生这种情况时,CPU只是坐在那里闲置。 所以有人有这样的想法基本上有两套线程状态(PC +寄存器),以便另一个线程(可能在同一个进程,也许在不同的进程)可以完成工作,而另一个线程正在主存储器上等待。 这个概念有多个名称和实现,比如HyperThreading和Simultaneous Multithreading (简称SMT)。

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

  1. 用户空间线程
  2. 内核线程
  3. 两者的结合

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

内核线程的优点是能够使用阻塞I / O,除了将所有调度问题留给操作系统。 但是每个线程切换都需要陷入可能相对较慢的内核。 但是,如果由于I / O被阻塞而切换线程,这不是一个真正的问题,因为I / O操作可能已经把你困在内核中了。

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

回到术语的问题,你可以看到一个过程和一个执行的线程是两个不同的概念,你select使用哪个术语取决于你在说什么。 关于“轻量级过程”这个词,我个人并不认为这一点,因为它并没有真正地传达出“正在执行的线索”这个词。

一个应用程序由一个或多个进程组成。 一个最简单的过程就是一个执行程序。 一个或多个线程在进程的上下文中运行。 线程是操作系统分配处理器时间的基本单位。 线程可以执行进程代码的任何部分,包括当前正在被另一个线程执行的部分。 光纤是必须由应用程序手动调度的执行单元。 光纤在安排它们的线程的上下文中运行。

从这里偷来的

进程是代码,内存,数据和其他资源的集合。 线程是在进程范围内执行的一系列代码。 您可以(通常)在同一个进程中同时执行多个线程。

  • 每个进程都是一个线程(主线程)。
  • 但是每一个线程都不是一个过程。 它是一个过程的一部分(实体)。

更多关于并发编程的解释

  1. 一个进程有一个独立的执行环境。 一个进程通常具有一套完整的私有基本运行时资源; 特别是每个进程都有自己的内存空间。

  2. 线程存在于一个进程内 – 每个进程至less有一个线程。 线程共享进程的资源,包括内存和打开的文件。 这使得沟通成为有效但潜在的问题。

记住一般人,

在您的计算机上,打开Microsoft Word和Web浏览器。 我们称之为这两个过程

在微软的话,你键入一些东西,它会自动保存。 现在,你会发现编辑和保存并行发生。 这被称为线程。

进程是应用程序的执行实例。 这意味着什么? 那么,例如,当您双击Microsoft Word图标时,就会启动一个运行Word的进程。 线程是进程内的执行path。 另外,一个进程可以包含多个线程。 当您启动Word时,操作系统创build一个进程并开始执行该进程的主线程。

重要的是要注意一个线程可以做任何一个进程可以做的事情。 但是由于一个进程可以由多个线程组成,所以一个线程可以被认为是一个“轻量级”进程。 因此,一个线程和一个进程之间的本质区别就是每个人用来完成的工作。 线程用于小任务,而进程用于更多“重量级”任务 – 基本上是应用程序的执行。

线程和进程之间的另一个区别是同一进程内的线程共享相同的地址空间,而不同的进程则不同。 这允许线程读取和写入相同的数据结构和variables,并且还促进线程之间的通信。 过程之间的通信也被称为IPC或进程间通信,是相当困难和资源密集型的。

进程和线程都是独立的执行序列。 典型的区别是,线程(同一进程)在共享内存空间中运行,而进程在单独的内存空间中运行。

处理

是一个正在执行的程序。 它具有文本部分,即程序代码,当前活动由程序计数器的值和处理器内容寄存器表示。 它还包含包含临时数据(例如函数参数,返回地址和局部variables)和包含全局variables的数据部分的进程堆栈。 一个进程也可能包括一个堆,它是在进程运行时dynamic分配的内存。

线

线程是CPU利用率的基本单位; 它包含一个线程ID,一个程序计数器,寄存器集和一个堆栈。 它与属于同一进程的其他线程共享其代码段,数据段和其他操作系统资源,如打开的文件和信号。

– 从高尔文的操作系统采取

试图回答这个有关Java世界的问题。

一个进程是一个程序的执行,但是一个线程是进程内的一个执行序列。 一个进程可以包含多个线程。 线程有时被称为轻量级进程

例如:

示例1:JVM在单个进程中运行,JVM中的线程共享属于该进程的堆。 这就是为什么几个线程可以访问同一个对象。 线程共享堆并有自己的堆栈空间。 这是一个线程如何调用一个方法以及它的局部variables是如何保持线程安全的。 但是堆不是线程安全的并且为了线程安全必须被同步。

示例2:程序可能无法通过读取按键来绘制图片。 程序一定要充分注意键盘的input,缺乏一次处理多个事件的能力会导致麻烦。 这个问题的理想解决scheme是同时执行一个程序的两个或多个部分。 线程允许我们这样做。 这里画图是一个过程,阅读击键是子过程(线程)。

线程和进程都是操作系统资源分配的primefaces单位(即有一个描述CPU时间如何分配的并发模型,以及拥有其他操作系统资源的模型)。 有一个区别在于:

  • 共享资源(线程根据定义共享内存,除了堆栈和局部variables之外,它们不拥有任何东西;进程也可以共享内存,但是由OS维护的还有一个单独的机制)
  • 分配空间(进程的内核空间与线程的用户空间)

上面的Greg Hewgill对于“process”这个词的Erlang含义是正确的, 在这里有一个关于Erlang为什么可以做轻量级处理的讨论。

线程和进程的区别?

进程是应用程序的执行实例,线程是进程内的执行path。 此外,一个进程可以包含多个线程。重要的是要注意,一个线程可以做任何一个进程可以做的事情。 但是由于一个进程可以由多个线程组成,所以一个线程可以被认为是一个“轻量级”进程。 因此,一个线程和一个进程之间的本质区别就是每个人用来完成的工作。 线程用于小任务,而进程用于更多“重量级”任务 – 基本上是应用程序的执行。

线程和进程之间的另一个区别是同一进程内的线程共享相同的地址空间,而不同的进程则不同。 这允许线程读取和写入相同的数据结构和variables,并且还促进线程之间的通信。 过程之间的通信也被称为IPC或进程间通信,是相当困难和资源密集型的。

以下是线程和进程之间的差异摘要:

  1. 线程比stream程更容易创build,因为它们不需要单独的地址空间。

  2. multithreading需要仔细编程,因为线程共享一次只能由一个线程修改的数据结构。 与线程不同,进程不共享相同的地址空间。

  3. 线程被认为是轻量级的,因为它们比进程使用的资源要less得多。

  4. 进程是相互独立的。 线程,因为它们共享相同的地址空间是相互依赖的,所以必须小心,以便不同的线程不会彼此相继。
    这是说明上述#2的另一种方式。

  5. 一个进程可以由多个线程组成。

从采访者的angular度来看,我基本上只想听到3件主要的事情,除了像一个进程这样明显的事情可以有多个线程:

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

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

  • 程序中的所有线程都必须运行相同的可执行文件。 另一方面,subprocess可以通过调用一个exec函数来运行不同的可执行文件。
  • 错误的线程可能会损害同一进程中的其他线程,因为线程共享相同的虚拟内存空间和其他资源。 例如,在一个线程中通过未初始化的指针进行的内存写操作会破坏对另一个线程可见的内存。
  • 另一方面,一个错误的过程不能这样做,因为每个过程都有一个程序存储空间的副本。
  • 复制新进程的内存相对于创build新线程会增加额外的性能开销。 但是,只有在内存更改时才执行复制,所以如果subprocess只读取内存,则惩罚最小。
  • 线程应该用于需要细粒度并行的程序。 例如,如果一个问题可以分解为多个几乎相同的任务,则线程可能是一个不错的select。 程序应该用于需要更粗略的并行性的程序。
  • 在线程之间共享数据是微不足道的,因为线程共享相同的内存。 (但是,必须非常小心避免竞争条件。)在进程间共享数据需要使用IPC机制。 这可能会更麻烦,但使多个进程不太可能遭受并发错误。

以下是我从“守则”项目的其中一篇文章中得到的内容。 我想这可以解释清楚所需的一切。

线程是将工作负载分解为单独的执行stream的另一种机制。 一个线程比一个进程更轻。 这意味着,它提供的灵活性不如完整stream程,但可以更快地启动,因为操作系统的设置较less。 当一个程序由两个或多个线程组成时,所有线程共享一个内存空间。 进程被赋予单独的地址空间。 所有的线程共享一个堆。 但是每个线程都有自己的堆栈。

  1. 基本上,一个线程是一个进程的一部分,没有进程线程将无法工作。
  2. 一个线程是轻量级的,而这个过程是重量级的。
  3. 进程间的通信需要一些时间,而线程则需要较less的时间
  4. 线程可以共享相同的内存区域,而进程是分开的。

过程和线程的真实世界的例子 这将给你关于线程和过程的基本思想 在这里输入图像描述

我从Scott Langham的答案中借用了上述信息 – 谢谢

  1. 一个线程运行在一个共享内存空间中,但一个进程运行在一个单独的内存空间中
  2. 线程是一个轻量级的过程,但一个过程是一个重量级的过程。
  3. 线程是进程的一个子types。

处理:

  1. 过程是一个沉重的过程。
  2. 进程是一个单独的程序,具有独立的内存,数据,资源等。
  3. 过程是使用fork()方法创build的。
  4. 进程之间的上下文切换非常耗时。

例:
说,打开任何浏览器(Mozilla,Chrome,IE)。 在这一点上,新的过程将开始执行。

主题:

  1. 线程是轻量级进程。线程捆绑在进程内。
  2. 线程有共享内存,数据,资源,文件等
  3. 线程是使用clone()方法创build的。
  4. 线程之间的上下文切换并不像Process那么耗时。

例:
在浏览器中打开多个选项卡。

 Process: program under execution is known as process Thread: Thread is a functionality which is executed with the other part of the program based on the concept of "one with other" so thread is a part of process.. 

试图从Linux内核的OS视图来回答它

一个程序在进入内存时就成为一个进程。 一个进程有自己的地址空间,意思是在内存中有不同的段,例如用于存储编译代码的.text segement,用于存储未初始化的静态variables或全局variables的.bss等等。每个进程都有自己的程序计数器和user-spcae 。 在内核内部,每个进程都有自己的内核堆栈(为了安全性问题与用户空间堆栈分开)和一个名为task_struct的结构,一般抽象为进程控制块,存储进程的所有信息,如进程的优先级,状态,(和一大堆其他块)。 一个进程可以有多个执行线程。

来到线程,它们驻留在一个进程中,共享父进程的地址空间以及线程创build时可以传递的其他资源,如文件系统资源,共享未决信号,共享数据(variables和指令),从而使线程轻量级,因此允许更快的上下文切换 在内核中,每个线程都有自己的内核堆栈以及定义线程的task_struct结构。 因此内核查看与不同实体相同进程的线程,并且可以自行调度。 同一个进程中的线程共享一个叫做线程组ID( tgid )的公共ID,同时它们也有一个唯一的ID,称为进程ID( pid )。

在构build包含multithreading的Python(解释型语言)的algorithm的同时,我惊讶地发现,与我之前构build的顺序algorithm相比,执行时间并不是那么好。 为了理解这个结果的原因,我做了一些阅读,并相信我所学到的东西提供了一个有趣的背景,从而更好地理解multithreading和多进程之间的差异。

多核系统可能会执行多个线程,所以Python应该支持multithreading。 但是Python不是一种编译语言,而是一种解释型语言1 。 这意味着程序必须被解释才能运行,而解释程序在开始执行之前并不知道该程序。 但是,它知道的是Python的规则,然后dynamic地应用这些规则。 Python中的优化必须主要是解释器本身的优化,而不是要运行的代码。 这与诸如C ++之类的编译语言形成鲜明对比,并且对Python中的multithreading产生影响。 具体来说,Python使用Global Interpreter Lock来pipe理multithreading。

另一方面编译好的语言编译好了。 该程序是“完全”处理,首先根据其语法定义进行解释,然后映射到语言不可知的中间表示,最后链接成可执行代码。 这个过程允许代码高度优化,因为它在编译时都是可用的。 各种程序交互和关系是在创build可执行文件时定义的,并且可以做出关于优化的稳健决策。

在现代环境中,Python的解释器必须允许multithreading,并且这必须既安全又高效。 这就是解释型语言和编译型语言之间的区别。 解释器不得干扰来自不同线程的内部共享数据,同时优化处理器的计算使用。

如前所述,进程和线程都是独立的顺序执行,主要区别在于内存在进程的多个线程之间共享,而进程隔离内存空间。

在Python中,全局解释器锁可防止不同线程同时访问数据。 它要求在任何Python程序中只能有一个线程可以随时执行。 另一方面,可以运行多个进程,因为每个进程的内存都与其他进程隔离,进程可以在多个内核上运行。


1 Donald Knuth对“计算机程序devise艺术:基础algorithm”中的解释程序有很好的解释。

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

线程可以访问每个其他的内存,并且由操作系统以交错的方式进行调度,以便它们似乎并行运行(或者与多核并行运行)。

另一方面, 进程存在于由MMU提供和保护的虚拟内存私有沙箱中。 这是方便的,因为它使:

  1. 让整个系统崩溃的过程。
  2. 通过使其他进程数据不可见和不可访问来维护安全性。 stream程内部的实际工作由一个或多个线程处理。

处理:

  • 一个进程有单独的虚拟地址空间。 在同一个系统上同时运行的两个进程不会相互重叠。

  • 每个进程都有自己的数据段以及独立的内存偏移量。

  • 进程使用进程间通信技术来与其他进程交互。
  • 进程没有像线程一样的同步开销。

线:

  • 线程是一个进程内的实体。 一个进程的所有线程共享其虚拟地址空间和系统资源,但他们有自己的堆栈创build。
  • 该进程创build的所有线程共享相同的数据段。
  • 线程不需要进程间通信技术,因为它们不是完全独立的地址空间。 他们共享相同的地址空间; 因此,他们可以直接与进程的其他线程进行通信。
  • 进程的线程共享相同的地址空间; 因此在进程地址空间内同步对共享数据的访问变得非常重要。
  • 线程可以很容易创build,不需要重复的资源。

同一进程中的线程共享内存,但是每个线程都有自己的堆栈和寄存器,线程在堆中存储线程特定的数据。 线程从不独立执行,所以与进程间通信相比,线程间通信要快得多。

进程永远不会共享相同的内存。 当一个subprocess创build它时,会复制父进程的内存位置。 进程通信通过使用pipe道,共享内存和消息parsing来完成。 线程之间的上下文切换非常缓慢。

他们几乎一样…但是关键的区别是线程是轻量级的,一个进程在上下文切换,工作负载等方面是重量级的。

线程和进程有什么区别? 是一个很好的写过程与线程。

示例1:JVM在单个进程中运行,JVM中的线程共享属于该进程的堆。 这就是为什么几个线程可以访问同一个对象。 线程共享堆并有自己的堆栈空间。 这是一个线程如何调用一个方法和它的局部variables保持线程安全的从其他线程。 但是堆不是线程安全的并且为了线程安全必须被同步。

进程是应用程序的执行实例。

这意味着什么? 那么,例如,当您双击Microsoft Word图标时,就会启动一个运行Word的进程。

线程是进程内的执行path。 另外,一个进程可以包含多个线程。

当您启动Word时,操作系统创build一个进程并开始执行该进程的主线程。