进程和线程之间的技术区别是什么?
我感觉像“进程”这样的词被过度使用了,而且还有硬件和软件线程。像Erlang这样的语言中的轻量级进程怎么样?是否有明确的理由使用一个术语而不是另一个术语?
进程和线程之间的技术区别是什么?
我感觉像“进程”这样的词被过度使用了,而且还有硬件和软件线程。像Erlang这样的语言中的轻量级进程怎么样?是否有明确的理由使用一个术语而不是另一个术语?
当前回答
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)在这种情况下,它只是做它自己的事情,然后退出。你不能用“线程”/“进程”这样做。莱纳斯牌手表
其他回答
它们几乎一样。。。但关键的区别在于线程是轻量级的,而进程在上下文切换、工作负载等方面是重量级的。
线程是一个子进程,它们共享一个进程内的代码、数据和文件等公共资源。然而,两个进程无法共享资源(例外情况是,如果一个进程(父进程)分叉为另一个进程,则默认情况下,它们可以共享资源。),对CPU的资源要求较高的负载,而线程在此上下文中要轻得多。虽然两者都有相同的功能。场景中,考虑一个单线程进程由于I/o而被阻塞,那么整个1将进入等待状态,但当多线程进程被I/o阻塞时,其唯一的1个I/o相关线程将被阻塞。
关于并发编程的更多解释
流程有一个独立的执行环境。一个进程通常有一套完整的、私有的基本运行时资源;特别是,每个进程都有自己的内存空间。
线程存在于一个进程中-每个进程至少有一个线程。线程共享进程的资源,包括内存和打开的文件。这有助于高效但可能存在问题的沟通。
来源:Java™ 教程:进程和线程
记住普通人的一个例子:
在计算机上,打开Microsoft Word和web浏览器。我们称这两个过程为。
在Microsoft Word中,您键入一些内容,它会自动保存。现在,您已经观察到编辑和保存是并行进行的——在一个线程上编辑,在另一个线程中保存。
线程和进程之间的区别?
进程是应用程序的执行实例,线程是进程内的执行路径。此外,一个进程可以包含多个线程。需要注意的是,一个线程可以做一个进程所能做的任何事情。但是,由于一个进程可由多个线程组成,因此可以将一个线程视为“轻量级”进程。因此,线程和进程之间的本质区别在于每个线程用来完成的工作。线程用于小型任务,而进程用于更“重量级”的任务——基本上是应用程序的执行。
线程和进程之间的另一个区别是,同一进程中的线程共享相同的地址空间,而不同的进程不共享。这允许线程读取和写入相同的数据结构和变量,也方便了线程之间的通信。进程之间的通信(也称为IPC或进程间通信)非常困难,而且资源密集。
这里总结了线程和进程之间的区别:
线程比进程更容易创建,因为它们不需要单独的地址空间。多线程需要仔细编程,因为线程共享只能由一个线程修改的数据结构一次。与线程不同,进程不共享相同的地址空间。线程被认为是轻量级的,因为它们使用资源少于流程。流程彼此独立。线程,因为它们共享同一地址空间是相互依赖的,因此请谨慎必须采取措施,以使不同的线程不会相互踩踏。这真的是另一种方式来说明上面的#2。一个进程可以由多个线程组成。
到目前为止,我找到的最好答案是Michael Kerrisk的《Linux编程界面》:
在现代UNIX实现中,每个进程可以有多个线程执行。设想线程的一种方式是作为一组进程共享同一虚拟内存以及一系列其他属性。每个线程执行相同的程序代码并共享相同的数据区域和堆。但是,每个线程都有自己的堆栈包含局部变量和函数调用链接信息。[LPI 2.12]
这本书非常清晰;JuliaEvans在本文中提到了它在澄清Linux组真正工作方式方面的帮助。
在用Python(解释语言)构建包含多线程的算法时,我惊讶地发现,与我之前构建的顺序算法相比,执行时间并没有任何改善。为了理解导致这种结果的原因,我做了一些阅读,并相信我所学到的内容提供了一个有趣的背景,可以更好地理解多线程和多进程之间的差异。
多核系统可能会执行多个线程,因此Python应该支持多线程。但Python不是一种编译语言,而是一种解释语言1。这意味着必须对程序进行解释才能运行,并且在程序开始执行之前,解释器不知道程序。然而,它所知道的是Python的规则,然后动态地应用这些规则。Python中的优化必须主要是解释器本身的优化,而不是要运行的代码。这与C++等编译语言形成对比,并对Python中的多线程产生影响。具体来说,Python使用全局解释器锁来管理多线程。
另一方面,编译语言是编译的。程序被“完全”处理,首先根据其语法定义进行解释,然后映射到语言不可知的中间表示,最后链接到可执行代码中。这个过程允许代码得到高度优化,因为在编译时所有代码都可用。在创建可执行文件时定义了各种程序交互和关系,可以做出关于优化的稳健决策。
在现代环境中,Python的解释器必须允许多线程,这必须既安全又高效。这就是解释语言与编译语言的区别所在。解释器必须不干扰来自不同线程的内部共享数据,同时优化处理器的计算使用。
如前几篇文章所述,进程和线程都是独立的顺序执行,主要区别在于内存在进程的多个线程之间共享,而进程隔离了它们的内存空间。
在Python中,全局解释器锁防止不同线程同时访问数据。它要求在任何Python程序中,任何时候只能执行一个线程。另一方面,可以运行多个进程,因为每个进程的内存都与任何其他进程隔离,并且进程可以在多个内核上运行。
唐纳德·克努思在《计算机编程的艺术:基本算法》中对解释例程有很好的解释。