计算机的线程和进程的区别理解,不是编程上的进程和线程

看了一遍排在前面的答案,类似”进程是资源分配的最小单位,线程是CPU调度的最小单位“这样的回答感觉太抽象,都不太容易让人理解。

做个简单的比喻:进程=火车,线程=车厢

  • 线程在进程下行进(单纯的车厢无法运行)
  • 一个进程可以包含多个线程(一辆火车可以有多个车厢)
  • 不同进程间数据很难共享(一辆火车上的乘客很难换到另外一辆火车,比如站点换乘)
  • 同一进程下不同线程间数据很易共享(A车厢换到B车厢很容易)
  • 进程要比线程消耗更多的计算机资源(采用多列火车相比多个车厢更耗资源)
  • 进程间不会相互影响,一个线程挂掉将导致整个进程挂掉(一列火车不会影响到另外一列火车,但是如果一列火车上中间的一节车厢着火了,将影响到所有车厢)
  • 进程可以拓展到多机,进程最多适合多核(不同火车可以开在多个轨道上,同一火车的车厢不能在行进的不同的轨道上)
  • 进程使用的内存地址可以上锁,即一个线程使用某些共享内存时,其他线程必须等它结束,才能使用这一块内存。(比如火车上的洗手间)-"互斥锁"
  • 进程使用的内存地址可以限定使用量(比如火车上的餐厅,最多只允许多少人进入,如果满了需要在门口等,等有人出来了才能进去)-“信号量”


<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>



首先来一句概括的总论:进程和线程都是一个时间段的描述,是CPU工作时间段的描述。是运行中的程序指令的一种描述,这需要与程序中的代码区别开来。

另外注意这里我说的进程线程概念,和编程语言中的API接口对应的进程/线程是有差异的。

下面细说背景
CPU+RAM+各种资源(比如显卡,光驱,键盘,GPS, 等等外设)构成我们的电脑,但是电脑的运行,实际就是CPU和相关寄存器以及RAM之间的事情。

一个最最基础的事实:CPU太快,太快,太快了,寄存器仅仅能够追的上他的脚步,RAM和别的挂在各总线上的设备则难以望其项背。那当多个任务要执行的时候怎么办呢?轮流着来?或者谁优先级高谁来?不管怎么样的策略,一句话就是在CPU看来就是轮流着来。而且因为速度差异,CPU实际的执行时间和等待执行的时间是数量级的差异。比如工作1秒钟,休息一个月。所以多个任务,轮流着来,让CPU不那么无聊,给流逝的时间增加再多一点点的意义。这些任务,在外在表现上就仿佛是同时在执行。

一个必须知道的事实:执行一段程序代码,实现一个功能的过程之前 ,当得到CPU的时候,相关的资源必须也已经就位,就是万事俱备只欠CPU这个东风。所有这些任务都处于就绪队列,然后由操作系统的调度算法,选出某个任务,让CPU来执行。然后就是PC指针指向该任务的代码开始,由CPU开始取指令,然后执行。

这里要引入一个概念:除了CPU以外所有的执行环境,主要是寄存器的一些内容,就构成了的进程的上下文环境。进程的上下文是进程执行的环境。当这个程序执行完了,或者分配给他的CPU时间片用完了,那它就要被切换出去,等待下一次CPU的临幸。在被切换出去做的主要工作就是保存程序上下文,因为这个是下次他被CPU临幸的运行环境,必须保存。

串联起来的事实:前面讲过在CPU看来所有的任务都是一个一个的轮流执行的,具体的轮流方法就是:先加载进程A的上下文,然后开始执行A,保存进程A的上下文,调入下一个要执行的进程B的进程上下文,然后开始执行B,保存进程B的上下文。。。

========= 重要的东西出现了========
进程和线程就是这样的背景出来的,两个名词不过是对应的CPU时间段的描述,名词就是这样的功能。

  • 进程就是上下文切换之间的程序执行的部分。是运行中的程序的描述,也是对应于该段CPU执行时间的描述。
  • 在软件编码方面,我们说的进程,其实是稍不同的,编程语言中创建的进程是一个无限loop,对应的是tcb块。这个是操作系统进行调度的单位。所以和上面的cpu执行时间段还是不同的。
  • 进程,与之相关的东东有寻址空间,寄存器组,堆栈空间等。即不同的进程,这些东东都不同,从而能相互区别。

线程是什么呢?
进程的颗粒度太大,每次的执行都要进行进程上下文的切换。如果我们把进程比喻为一个运行在电脑上的软件,那么一个软件的执行不可能是一条逻辑执行的,必定有多个分支和多个程序段,就好比要实现程序A,实际分成 a,b,c等多个块组合而成。那么这里具体的执行就可能变成:

程序A得到CPU =》CPU加载上下文,开始执行程序A的a小段,然后执行A的b小段,然后再执行A的c小段,最后CPU保存A的上下文。

这里a,b,c的执行是共享了A进程的上下文,CPU在执行的时候仅仅切换线程的上下文,而没有进行进程上下文切换的。进程的上下文切换的时间开销是远远大于线程上下文时间的开销。这样就让CPU的有效使用率得到提高。这里的a,b,c就是线程,也就是说线程是共享了进程的上下文环境,的更为细小的CPU时间段。线程主要共享的是进程的地址空间。

到此全文结束,再一个总结:

进程和线程都是一个时间段的描述,是CPU工作时间段的描述,不过是颗粒大小不同。

注意这里描述的进程线程概念和实际代码中所说的进程线程是有区别的。编程语言中的定义方式仅仅是语言的实现方式,是对进程线程概念的物化

以上纯属于个人的理解,有不同见解,欢迎讨论!

 
 
 
 
<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>
 
 
作者:王辉
链接:https://www.zhihu.com/question/25532384/answer/243297439
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

这个问题,是操作系统里问的最多的问题之一,也是被误解最深的概念之一。Alan Kay说过,好的角度可以提升80分的智商。理解它们的差别,我从资源使用的角度出发。所谓的资源就是计算机里的中央处理器,内存,文件,网络等等。

进程,在一定的环境下,把静态的程序代码运行起来,通过使用不同的资源,来完成一定的任务。比如说,进程的环境包括环境变量,进程所掌控的资源,有中央处理器,有内存,打开的文件,映射的网络端口等等。

这里我把进程对内存的管理稍微展开说一下。一个系统中,有很多进程,它们都会使用内存。为了确保内存不被别人使用,每个进程所能访问的内存都是圈好的。一人一份,谁也不干扰谁。还有内存的分页,虚拟地址我就不深入探讨了。这里给大家想强调的就是,进程需要管理好它的资源。

其中,线程作为进程的一部分,扮演的角色就是怎么利用中央处理器去运行代码。这其中牵扯到的最重要资源的是中央处理器和其中的寄存器,和线程的栈(stack)。这里想强调的是,线程关注的是中央处理器的运行,而不是内存等资源的管理。

当只有一个中央处理器的时候,进程中只需要一个线程就够了。随着多处理器的发展,一个进程中可以有多个线程,来并行的完成任务。比如说,一个web服务器,在接受一个新的请求的时候,可以大动干戈的fork一个子进程去处理这个请求,也可以只在进程内部创建一个新的线程来处理。线程更加轻便一点。线程可以有很多,但他们并不会改变进程对内存(heap)等资源的管理,线程之间会共享这些资源。

总结一下,我上面的解释是通过计算机操作系统的角度出发的。进程和线程不是同一个层面上的概念,线程是进程的一部分,线程主抓中央处理器执行代码的过程,其余的资源的保护和管理由整个进程去完成。
 
 
 
本文来源:https://www.zhihu.com/question/25532384
posted @ 2020-11-11 19:57  建铭博客  阅读(247)  评论(0编辑  收藏  举报