进程和线程的区别

进程(任务)

什么是进程?

按照字面意思可以理解为进程是正在运行的程序

image-20220322105002388

这些可执行文件,都是文件,平时都静静地躺在硬盘中。在双击之前,不会对操作系统有任何的影响。

一旦执行这些文件,操作系统会将这些 .exe 文件加载到内存中,并且让CPU开始执行这些.exe内部的一些指令(exe里面存放着很多这个程序相对应的二进制指令)。

这个时候,这些exe文件就开始进行一些具体的工作了,把这些运行起来的可执行文件,称之为“进程”

image-20220322105700432

对于java代码来说,最后都是通过java进程跑起来的(JVM)

进程(process)还有另一个名字 任务(task)

操作系统是如何管理进程的

  1. 先描述一个进程(明确出一个进程上面的相关属性)

进程上的相关属性在操作系统中,主要通过C/C++实现的

此处的描述其实就是用的C的”结构体“(和Java的类差不多)

操作系统中,描述进程的结构体,成为PCB(process control block 进程控制块)

  1. 再组织若干个进程(使用一些数据结构,把很多描述进程的信息放在一起,方便进行增删改查)

典型的实现(Linux操作系统),就是使用一个双向链表将每个进程的PCB给串起来

所谓的"创建进程"就是先创建出PCB,然后把PCB加到双向链表中

所谓的"销毁进程",就是找到链表上的PCB,并且从链表上删除

所谓的"查看任务管理器“,就是遍历链表

很多代码其实最终全部都落在操作系统上

进程中的PCB中的一些属性

pid(进程id)

进程的身份标识 进程的身份证号

内存指针

指明了这个进程要执行的代码/指令在内存的哪里,以及进程执行中依赖的数据在那里

当运行一个exe,此时操作系统会把这个exe加载到内存中,变成进程

文件描述符表

程序运行过程中,经常要和文件打交道.(文件是在硬盘上的)

进程每次打开一个文件,就会在文件描述符表多增一项 (文件描述符表就可以视为是一个数组,里面的每个元素就是一个结构体,就对应一个文件的相关信息)

一个进程只要一启动,不管代码中个是否写了打开/操作文件的代码,都会默认的打开三个文件(系统自带的)

标准输入(System.in),标准输出(System.out) 标准错误(System.err)

文件描述符表的下标就是文件描述符.

要想让一个进程正常工作,就需要给这个进程分配一些系统资源

内存 硬盘 cpu ----->硬件的支持


进程调度

什么是进程调度

进程调度是了解进程管理的重要话题

现在的操作系统一般为 “多任务操作系统”,一个系统同时执行很多的任务

前提:系统上任务的数量(进程的数量)有几十个,上百个,但是一个cpu核数是有限的(例如6核)

进程调度 : cpu有限的核心可以进行很多很多的任务.

进程调度相关的一些属性

关于进程调度,这里并不是那么容易可以理解,所以用一个实例来代入思考一下.
所谓的调度就是时间管理,假如博主是一个妹子,长得好看,身材好,还会说话,所以有很多追求者,但是我的要求很高,我想要有钱的,长的帅的,并且还会舔我的,然现实中三点全部都具备的男孩子基本没有,我只能选择一个折中的办法,同时谈三个

A :有钱

B:长的好看

C:比较会舔

宏观上,我谈了三个男朋友,但是微观上,我只谈了一个.

谈了三个以后,不可能让他们见面,不然全都乱套了,所以我灵机一动,排了一个时间表

周一:和A逛街

周二:和B去上课

周三:和C看电影

周四…

image-20220322123837293

image-20220322123858390

image-20220322123913382

image-20220322123928529

状态:描述了当前这个进程接下来应该怎么调度

  1. 就绪状态:随时可以去CPU上执行
  2. 阻塞状态/睡眠状态:暂时不可以去CPU上执行

优先级:先给谁分配时间,后给谁分配时间,以及分配时间的长短

记账信息:统计了每个进程都分别被执行了多久,分别都执行了那些指令 ,分别排队了多久,以及给进程调度提供指导依据

上下文:表示上次进程被调度出CPU的时候,当时程序的执行状态,下次进程上CPU的时候,就可以回复之前的状态,然后继续往下执行

进程被调度出CPU之前,要先吧CPU中所有的寄存器中的数据保存到内存(PCB的上下文字段)中,就相当于存档了;下次进程再次被调度上CPU的时候,就可以从刚才的内存中恢复这些数据到寄存器中,相当于读档。

并行和并发

并行:微观上,两个cpu核心同时执行两个任务的代码

并发:微观上,一个cpu核心,先执行一会儿任务1,再执行一会儿任务2,再执行一会儿任务3…在执行一会儿任务1(只要切换的足够快,宏观上看起来,就好像同时执行这么多的任务)

内存分配

由于操作系统上,同时运行着多个进程,如果某个进程出现了bug,进程崩溃了,会不会影响到其他的进程?所以就需要“进程的独立性”来保证,依仗“虚拟地址空间”

进程的独立性

操作系统上,同时运行着多个进程,如果某个进程出现了bug,进程崩溃了,并不会影响到其他的进程,这就是进程的独立性保证的,依仗了”虚拟地址空间“

但是在实际工作中,有些进程有的手需要相互交互,这时候就需要进程之间的通信

进程之间的通信

比如两个进程之间相互隔离,是不能交互的,但是操作系统提供了类似公共空间,进程A可以把数据放在公共空间,进程B再到公共空间取走数据。

操作系统中,提供的公共空间有很多种,并且各有特点,有点存储空间大,有的小,有点速度快,有的慢。 操作系统提供了多种这样的进程间通信机制

现在主要使用的进程通信方式:

  1. 文件操作
  2. 网络操作

线程

线程是啥?

一个线程就是一个 “执行流”,每个线程之间都可以按照顺序执行自己的代码. 多个线程之间 “同时” 执行着多份代码.

比如我们可以把进程比作一个“工厂”,而线程就是”工厂“里的”生产线“,一个“工厂”可以有多个“生产线”,所以一个进程可以有点多个线程

进程和线程在并发编程上的区别

首先我们需要知道,我们要有进程是因为我们的系统支持多任务,而且程序员需要“并发编程“

通过多进程可以实现并发编程,但是如果频繁的创建/销毁进程,这件事情的成本很高,同样的如果频繁的调度进程,也是需要很多成本的。

image-20220322125911719

所以为了解决成本高这个问题,有两个思路

  1. 进程池

进程池虽然可以解决上述问题,提高效率,同时也存在问题,池子里的闲置进程,不使用的情况下也在消耗系统资源,消耗的系统资源太多了。

  1. 使用多线程来实现并发编程

线程比进程更轻量,每个进程可以执行一个任务,每个线程也可以执行一个任务,也能够实现并发编程

线程比进程更轻量的原因

进程重在资源申请/释放

线程是包含在进程中的,一个进程中的多个线程,共用同一份资源(同一份内存+文件)

只有创建进程的第一个线程的时候(由于要分配资源)成本是相对高的,后续这个进程中创建其他线程,这个时候成本都是要相对应的低一些(不必再分批资源)

创建线程的成本比创建进程要低得多
销毁线程的成本比创建进程要低得多
调度线程的成本比创建进程要低得多

谈谈进程与线程的区别和联系?(重点)

  1. 进程包含线程,一个进程可以有一个线程,也可以有多个线程。
  2. 进程和线程都是为了处理并发编程这样的场景。但是进程有问题,频繁创建和释放的时候效率低;相比之下,线程更轻量,创建和释放效率更高(少了申请释放资源的过程)
  3. 操作系统创建进程,是要给进程分配资源,进程是操作系分配资源的基本单位,操作系统创建的线程,是要在CPU上调度执行,线程是操作系统调度执行的基本单位
  4. 进程具有独立性,每个进程有各自的虚拟地址空间,一个进程挂了不会影响其他进程,同一个进程中的多个线程,共用同一个内存空间,一个线程挂了可能会影响到其他的线程,甚至导致整个进程崩溃.
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值