进程和线程之间的技术区别是什么?
我感觉像“进程”这样的词被过度使用了,而且还有硬件和软件线程。像Erlang这样的语言中的轻量级进程怎么样?是否有明确的理由使用一个术语而不是另一个术语?
进程和线程之间的技术区别是什么?
我感觉像“进程”这样的词被过度使用了,而且还有硬件和软件线程。像Erlang这样的语言中的轻量级进程怎么样?是否有明确的理由使用一个术语而不是另一个术语?
当前回答
从面试官的角度来看,我基本上只想听到3件主要事情,除了像流程这样的显而易见的事情外,还有多个线程:
线程共享相同的内存空间,这意味着一个线程可以从其他线程的内存访问内存。进程通常不能。资源。资源(内存、句柄、套接字等)在进程终止时释放,而不是线程终止时释放。安全进程具有固定的安全令牌。另一方面,线程可以模拟不同的用户/令牌。
如果你想要更多,Scott Langham的回应几乎涵盖了所有内容。所有这些都是从操作系统的角度来看的。不同的语言可以实现不同的概念,如任务、轻线程等等,但它们只是使用线程(Windows上的光纤)的方式。没有硬件和软件线程。存在硬件和软件异常和中断,或者用户模式和内核线程。
其他回答
示例1:JVM在单个进程中运行,JVM中的线程共享属于该进程的堆。这就是为什么多个线程可以访问同一个对象。线程共享堆并拥有自己的堆栈空间。这就是一个线程对方法及其局部变量的调用如何保持与其他线程的线程安全。但是堆不是线程安全的,必须同步以确保线程安全。
进程是代码、内存、数据和其他资源的集合。线程是在进程范围内执行的一系列代码。您可以(通常)在同一进程中同时执行多个线程。
同一进程中的线程共享内存,但每个线程都有自己的堆栈和寄存器,线程在堆中存储线程特定的数据。线程从不独立执行,因此与进程间通信相比,线程间通信要快得多。
进程从不共享相同的内存。当子进程创建时,它会复制父进程的内存位置。进程通信通过使用管道、共享内存和消息解析来完成。线程之间的上下文切换非常缓慢。
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)在这种情况下,它只是做它自己的事情,然后退出。你不能用“线程”/“进程”这样做。莱纳斯牌手表
以下是我从代码项目的一篇文章中得到的内容。我想它清楚地解释了所需的一切。
线程是另一种将工作负载拆分为单独的执行流。线程的重量比进程轻。这这意味着,它提供的灵活性不如全面流程,但可以启动速度更快,因为操作系统设置当程序由两个或多个线程组成时线程共享单个内存空间。进程被赋予单独的地址空间。所有线程共享一个堆。但每个线程都有自己的堆栈。