JAVAee-多线程初阶-进程调度基本过程

什么是进程/任务(process/tesk)?

 我们电脑中的.exe文件,如果我们不去双击运行它的话,他只会静静的躺在你的硬盘空间里,也就是说在我们双击它之前,它不会对我们的系统产生任何影响。

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

第一步 先描述一个进程(描述一个进程上面的一些相关属性):

操作系统中使用"PCB"(进程控制块)来描述一个进程,在操作系统里面主要使用c/c++来实现相关属性,此处描述就是用C语言中的"结构体",操作系统中描述进程的结构体称为"PCB"

第二步 再组织若干个进程(使用一些数据结构,将描述进程的信息放在一起,以便于增上改查):

使用双向链表将每个进程的PCB来串起来, 这里指的是Linux系统,因为每个操作系统的类型不同,内部的实现也是不同的,至于Windows和iOS是如何实现的我们也不得而知了.

还有一些所谓的进程操作:

创建进程:就是先创建出PCB,然后再将PCB加到双向链表中.

销毁线程:就是找到链表上的PCB,然后将其从链表上删除.

查看任务管理器,实际就是遍历整个链表.

PCB的一些属性:

pid(进程id):

就是进程的身份标识(类比每个人的身份证号)

内存指针:

指明了这个进程要执行的指令/代码在内存的哪里,以及这个进程执行依赖的数据在哪里~~当运行一个.exe,此时操作系统就会把这个.exe加载到内存中,变成进程.

文件描述符表:

程序运行过程中,经常要和文件打交道,进程每次打开一个文件,就会在文件描述符表上多增加一项(这个文件描述符表可以视为一个数组,里面的每个元素又是一个结构体,就对应一个文件的相关信息)一个进程只要一启动,不管你代码中是否打开/操作文件的代码都会默认的打开三个文件~~(系统自动打开的):标准输入(System.in)标准输出(System.out)标准错误(System.err
这个文件描述符表的下标,就称为文件描述符~

进程调度的基本过程

进程调度的基本过程其实就是,操作系统在考虑如何将cpu资源分配给各个进程

上面的属性是一些基础的属性,下面的属性,主要是为了能够实现进程的调度.

状态:

就绪状态:指的是这个进程随时可以去cpu上执行.

阻塞状态/休眠状态:指的是这个进程暂时不能去cpu上执行.

优先级:

先给谁分配时间,后给谁分配时间,以及谁分的多,谁分的少.

记账信息:

统计了每个进程,都分别被执行了多久,分别都执行了哪些指令。分别都等了多久,目的是给进程调度提供指导依据的。

上下文:

描述上次进程被调度出cpu的时候的执行情况,再下一次进程被重新调度时,可以恢复到上一次的执行状态,并且继续往下执行.

进程被调度出cpu之前,要把cpu中的寄存器中的数据都保存到内存中(PCB的上下文字段中)

就好比有些游戏的存档

当下次进程再次被调度到cpu上时,就可以从内存中恢复这些数据到寄存器中.

健身安排:

我们可以用每周的健身安排,来加深印象,模拟一下进程调度.

我们健身大概分为4个部分:

A:手臂和肩膀

B:胸部和背部

C:腿

每周有七天,我们每天练一个部分,也可以不练,如果想要进步就要给自己安排合理的训练计划和时间安排.

ps:显然这就是并发,而规划训练时间的过程,就是调度的过程

站在上面的角度我们再来看一下PCB中的进程调度属性

状态

正常情况下,A,B,C三个部分我们都可以连,他们都是就绪状态.

但是如果你某次训练过度导致你的腿/C受伤了,那么就可以认为腿/C现在是阻塞状态/睡眠状态

这样状态的进程就暂时不会进行调度了(暂时不把你的腿部训练排在时间表上).

优先级

比如你的某个部位是你的弱项,那么你就可以多安排这个部位的训练.将其他部位的训练少安排一些.

比如周一.周三.你来训练你的胸部和背部~B

周二训练手臂和肩膀~A

周五来训练你的腿部~C

周六,周天休息,让身体来恢复

记账信息

如果长时间这样安排你的A部分肯定会进步,其他的部分就会相比之下没有那么厉害,那么你就要调整你的训练计划,将其他部位的训练强度加大.

上下文

因为你训练的日程比较近,你可能在某天练的部位不是你计划中当天要练到的部位,就会打乱你的计划,这个时候就需要你对你的训练做好记录,下次你也可以查到之前训练了什么,以及自己该训练那个部位了.

关于线程

为什么要有线程?

线程是啥?为啥要有线程?
因为我们的系统支持多任务了~(上古版本还是单任务)程序猿也就需要“并发编程”
通过多线程,是完全可以实现并发编程的~

但是有个小问题:
如果需要频繁的创建/销毁进程,这个事情的成本还是比较高的。
如果需要频繁的调度进程,这个事情成本也是比较高的

 那么如何解决这个问题呢?
主要有两个思路:
1.进程池~(数据库连接池,字符串常量池)
进程池虽然能解决上面的问题,提高效率,同时也存在问题,池子里的闲置进程,不使用的时候也在消耗系统资源,消耗的系统资源太多了~
2.使用线程来实现并发编程~
线程比进程更轻量,每个进程可以执行一个任务,每个线程也能执行一个任务(执行一段代码),也能进行并发编程。

ps:

创建线程的成本比创建进程的成本小得多.

销毁线程的成本比销毁进程的成本小得多.

调度线程的成本比调度进程的成本小得多.

为什么进程重线程轻呢?

进程重在资源申请释放(在仓库中找东西)

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

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

ps:这里我们还是多理解,可以结合一些生活中的例子,来加深对知识的理解.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

拧开瓶盖喝酸奶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值