进程与线程的理解

一、什么是进程和线程?

  专业解释:进程和线程都是一个时间段的描述,是CPU工作时间段的描述。进程是资源分配的最小单位,线程是CPU调度的最小单位

  进程可以说是一个“执行中的程序”。程序是指令、数据及其组织形式的描述,是一个没有生命的实体,只有处理器赋予程序生命时(操作系统执行之),它才能成为一个活动的实体,我们称其为进程。

  而我们可以在一个进程中创建多个线程,让它们在“同一时刻”(只是在CPU休息的时候让它继续马不停蹄的执行下一个程序)分别去做不同的工作了,极大的利用了CPU资源。这些线程共享同一块内存,线程之间可以共享对象、资源,如果有冲突或需要协同,还可以随时沟通以解决冲突或保持同步,而进程间不可以共享它们内部的资源,但可以共享内存,即进程共享操作系统空间资源。

二、出现的背景:

  CPU非常快,寄存器和RAM等的速度远不及CPU。当要执行多个任务时,CPU的处理方式仍然是依次解决。因为速度差异,CPU实际的执行时间和等待执行的时间是数量级的差异。比如工作1秒钟,休息一个月。所以多个任务,轮流着来,让CPU不那么无聊,给流逝的时间增加再多一点点的意义。这些任务,在外在表现上就仿佛是同时在执行(以为CPU的执行速度实在太快了)。
  执行一段程序代码之前 ,相关的资源必须已经就位,只等CPU执行。所有这些任务都处于就绪队列,然后由操作系统的调度算法,选出某个任务,让CPU来执行。执行的过程就是PC指针指向该任务的代码开始,由CPU开始取指令,然后执行。
  因此,CPU执行的顺序是:
  1、加载进程A的上下文,
  2、开始执行进程A,
  3、保存进程A的上下文,
  4、调入下一个要执行的进程B的进程上下文,
  5、开始执行进程B,
  6、保存进程B的上下文。
  这里的上下文是进程执行的环境,为什么要保存上下文呢?因为当这个程序执行完了,或者分配给他的CPU时间片用完了,那它就要被切换出去,等待下一次CPU的临幸。如果不保存上下文,那么下次他被CPU临幸的运行环境就找不到了。
  而通常一个进程运行的时间较长,每次执行都要切换上下文会造成效率低下,我们可以将进程分成多个代码组合块a,b,c,定义为线程a,b,c,线程的执行是共享了进程的上下文(资源共享),CPU在执行的时候仅仅切换线程的上下文,而不必进行进程上下文切换的。
  由此,CPU执行过程就可以更新为:
  1、程序A得到CPU
  2、CPU加载进程A的上下文,
  3、执行进程A的a小段,
  4、执行进程A的b小段,
  5、执行进程A的c小段,
  6、CPU保存进程A的上下文,
  7、调入下一个要执行的进程B的进程上下文,进行类似进程A的流程

三、一些专业术语
  1、线程的实现:创建线程——启动线程,如果不写启动命令,则不知道需要开始执行线程。
  2、解决线程冲突问题(几个线程都需要使用该资源):线程同步,即一个线程使用中,其他线程等待。
  3、几个进程的运行机制类似,将某一个定为主进程,其他成为子进程,这几个进程协同作用实现更大的功能,称为进程间同步。而在每个进程中都可以有一个或多个线程,一个线程的成为单线程,只能按顺序执行;多个线程的称为多线程,可以‘同时’执行程序。

 

四、形象比喻

  可以将进程和线程的关系比作火车与车厢、公司与工人的关系。

  • 线程在进程下行进(单纯的车厢无法运行)
  • 一个进程可以包含多个线程(一辆火车可以有多个车厢)
  • 不同进程间数据很难共享(一辆火车上的乘客很难换到另外一辆火车,比如站点换乘)
  • 同一进程下不同线程间数据很易共享(A车厢换到B车厢很容易)
  • 进程要比线程消耗更多的计算机资源(采用多列火车相比多个车厢更耗资源)
  • 进程间不会相互影响,一个线程挂掉将导致整个进程挂掉(一列火车不会影响到另外一列火车,但是如果一列火车上中间的一节车厢着火了,将影响到所有车厢)
  • 进程可以拓展到多机,进程最多适合多核(不同火车可以开在多个轨道上,同一火车的车厢不能在行进的不同的轨道上)
  • 进程使用的内存地址可以上锁,即一个线程使用某些共享内存时,其他线程必须等它结束,才能使用这一块内存。(比如火车上的洗手间)-"互斥锁"
  • 进程使用的内存地址可以限定使用量(比如火车上的餐厅,最多只允许多少人进入,如果满了需要在门口等,等有人出来了才能进去)-“信号量”
  
  电脑上每启动一个软件就是启动一个进程,而一个软件上有很多功能,执行一个功能就是执行一个线程。
 
 
五、进程间通信的方式
  进程间通信是一组编程接口,让程序员能够协调不同的进程,使之能在一个操作系统里同时运行,并相互传递、交换信息。这使得一个程序能够在同一时间里处理许多用户的要求。因为即使只有一个用户发出要求,也可能导致一个操作系统中多个进程的运行,进程之间必须互相通话。
  1、管道
  (1)无名管道(普通管道):数据只能单向流动,而且只能在具有亲缘关系的进程间(父子进程)使用。
  (2)有名管道(命名管道):数据只能单向流动,但它允许无亲缘关系进程间的通信。
  (3)高级管道(流管道):可以双向流动,将另一个程序当做一个新的进程在当前程序进程中启动。
  2、消息队列
   消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。
  3、信号量
  共享内存最大的问题是什么?就是多进程竞争内存的问题,就像类似于我们平时说的线程安全问题。信号量是一个计数器,可以用来控制多个进程对共享内存的访问。它常作为一种锁机制,防止某进程正在访问共享内存时,其他进程也访问该内存。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。
  例如信号量的初始值是 1,然后 a 进程来访问内存1的时候,我们就把信号量的值设为 0,然后进程b 也要来访问内存1的时候,看到信号量的值为 0 就知道已经有进程在访问内存1了,这个时候进程 b 就会访问不了内存1

  4、信号

  信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。

  5、共享内存

  共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的 IPC 方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号配合使用,来实现进程间的同步和通信。

  6、套接字( socket ) 

   套解字也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同机器间的进程通信。

 

该文仅作为自己对进程和线程的总结理解,摘录自以下文章:
作者:知乎用户
链接:https://www.zhihu.com/question/25532384/answer/411179772
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

作者:zhonyong
链接:https://www.zhihu.com/question/25532384/answer/81152571
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
 
作者:人民邮电出版社
链接:https://www.zhihu.com/question/25532384/answer/1598653960
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
 
作者:happyjava
链接:https://www.cnblogs.com/happy4java/p/11343072.html
来源:博客园
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
 
作者:E=mc²_
链接:https://blog.csdn.net/weixin_44653395/article/details/99686244
来源:CSDN
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

 

posted @ 2021-05-25 22:09  桃子|TTW  阅读(302)  评论(0)    收藏  举报