multithreading - 进程和线程的区别和联系 - 进程线程知乎




进程和线程有什么区别? (20)

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

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


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

herehere


  1. 基本上,线程是进程的一部分,没有进程线程无法工作。
  2. 线程是轻量级的,而过程是重量级的。
  3. 进程之间的通信需要一些时间,而线程需要更少的时间
  4. 线程可以共享相同的内存区域,而进程独立存在。

线程与进程的区别?

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

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

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

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

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

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

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

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


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

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

在MSDN上找到这里:
关于进程和线程

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


处理:

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

例:
说,打开任何浏览器(Mozilla,Chrome,IE)。 此时新流程将开始执行。

主题:

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

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


流程和线程的真实世界示例 这将给您关于线程和流程的基本概念

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


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

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

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


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

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


在构建包含多线程的Python(解释型语言)中的算法时,我惊讶地发现,与我之前构建的顺序算法相比,执行时间并没有更好。 为了理解这个结果的原因,我做了一些阅读,并且相信我学到的东西提供了一个有趣的背景,从中可以更好地理解多线程和多进程之间的差异。

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

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

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

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

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

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


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


更多关于并发编程的解释

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

  2. 线程存在于一个进程中 - 每个进程至少有一个线程。 线程共享进程的资源,包括内存和打开的文件。 这使得沟通有效但可能有问题。

记住一般人,

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

在微软的话,你输入一些东西,它会自动保存。 现在,你会观察到并行编辑和保存 - 在一个线程上编辑并保存在另一个线程上。


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

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

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

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

线程和进程都是操作系统资源分配的原子单位(即有一个描述CPU时间如何分配的并发模型,以及拥有其他操作系统资源的模型)。 有以下不同之处:

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

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


线程是CPU利用率的基本单位; 它包含线程ID,程序计数器,寄存器组和堆栈。 它与属于同一进程的其他线程的代码段,数据段和其他操作系统资源(如打开的文件和信号)共享。 传统(或重量级)流程具有单一控制线程。 如果一个进程有多个控制线程,它一次可以执行多个任务


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

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

例如:

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

示例2:程序可能无法通过读取按键来绘制图片。 该程序必须充分注意键盘输入,并且缺乏一次处理多个事件的能力将导致麻烦。 解决此问题的理想解决方案是同时无缝执行程序的两个或更多部分。 线程允许我们这样做。 这里画图是一个过程,读击键是子过程(线程)。


迄今为止我所见过的最好的短期定义来自Michael Kerrisk的“The Linux Programming Interface”:

在现代UNIX实现中,每个进程可以有多个执行线程。 设想线程的一种方式是共享相同虚拟内存的一组进程,以及一系列其他属性。 每个线程正在执行相同的程序代码并共享相同的数据区和堆。 但是,每个线程都有自己的包含本地变量和函数调用链接信息的堆栈。 [LPI 2.12]


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

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

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


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


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

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

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


首先,我们来看看理论方面。 您需要理解流程在概念上是什么,才能理解流程和线程之间的差异以及它们之间共享的内容。

我们从2.2.2节Tanenbaum的现代操作系统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将支持单个执行线程,通过单个程序计数器和一组寄存器来维护线程的状态。 但是如果有一个缓存未命中会发生什么? 从主存储器获取数据需要很长时间,而这种情况发生时,CPU只是坐在那里闲置。 所以有人想到基本上有两组线程状态(PC +寄存器),以便另一个线程(可能在同一进程中,也许在另一个进程中)可以在另一个线程在主存储器上等待时完成工作。 这个概念有多种名称和实现,例如超线程和同时多线程 (简称SMT)。

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

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

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

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

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

回过头来看术语问题,你可以看到一个过程和一个执行线程是两个不同的概念,你选择使用哪个术语取决于你在说什么。 关于“轻量级过程”这个术语,我个人并没有看到它的意义,因为它并没有真正传达正在发生的事情以及“执行线程”这个术语。





process