JavaEE第一篇
一、操作系统基础
(一)、进程
1.进程就是一个运行的程序或者是任务,就比如说我们打开任务管理器所看到的这些正在运行的程序它就是进程。
2.进程管理:实质上是操作系统它对进程的统一调度和管理。
那如何去描述一个进程?如何去组织这些数据呢?这里就好比学校里面学生很多,这些学生各自有自己事要做,学生个体就相当于一个进行,有很多个学生,那么就有很多进程,此时我们就需要通过一个东西也就是学号来描述每个学生,同时我们需要针对学生进行分类(学院、专业、班级等),此时就会通过一些手段,去管理学生这个群体。同理,对于进程来讲,我们在描述一个进程的时候,会使用结构体或者类,把这个进程它有哪些信息给表示出来。在组织这些进程的时候我们会采用一定的数据结构,将这些结构体或者对象放到一起这样便于管理。
对于上面提到的结构体,那么在结构体(PCB —> 程序控制块)里又有哪些属性呢?
(1)pid:类似我们的学生id,都是唯一标识身份信息的,所以在这里它表示的是进程唯一的身份标识。
(2)内存指针:表示当前这个进程使用的是内存的哪一部分。因为进程运行过程中,是会消耗一定的资源的,比如内存,所以进程运行的时候,这个内存指针表示它使用了哪些内存上的资源。
(3)文件描述符表:进程每次打开一个文件就会产生一个“文件描述符”(标识了这个被打开的文件),然后呢又因为一个进程它不一定只打开一个文件,而是可能打开多个文件,所以也就会产生一组文件描述符,我们将这些文件描述符像顺序表这样的结构里,就会构成文件描述符表。(也就是说进程在运行的时候使用了哪些硬盘上的资源)
(4)进程调度(描述和CPU资源相关的属性)
程序之所以能运行起来,全依仗CPU。每个程序,相当于一组“二进制指令”的集合。其中CPU它有一个概念,核心数。在任务管理器种我们可以看到相关信息,如下图是4核8线程的,也就是说CPU里有4个核心(4个做事的人),但是呢每个核心它相当于两个人,也就是4个人能做8个人的事。所以这个图表示的是4个物理核心,8个逻辑核心。
进程的并行:同一时刻,两个核心,同时执行两个进程,此时这个两个进程就是并行执行的。
进程的并发:一个核心,先执行进程1,执行一会之后,又去执行进程2,紧接着进程3……,此时进程之间的切换速度是非常快的,所以肉眼看起来就像是“同时”执行的,但实则不是这样的,在计算机内部,它是一个接着一个的。所以大部分情况下,并行和并发统称为并发。
(a)进程状态
进程基本状态如下图:
就绪态:进程已经准备好了,随时都可以在CPU上运行。(等待分配CPU,就绪队列)
执行态:进程已经获得CPU,正在运行。(已分配CPU,正在运行)
阻塞态:此刻的进程由于发生一些事件(IO请求,资源申请失败等)导致程序无法继续在CPU上执行。
(b)进程的优先级(狼多肉少)
进程之间的调度不一定是“公平”的,有的是需要优先调度的。(比如说,摆在我面前有几件事,去网吧,陪好友看电影,去完成作业,此时作业就是必须得先完成的,其它的都是次要的)。
(c)进程的上下文
上下文指的是描述了当前进程执行到哪里了,此时被中断了,那么我就得需要把这个进程进行到的这个前半部分操作记录下来,也就是存档记录,当我再次回来之后我就可以恢复到刚才的位置,(存档),从刚才获得的结果继续往后执行。这里的话就好比我正在家里洗碗,然后突然有客人来了,那么我就得暂时停下来,去招呼客人,那么当我完成招呼客人的这个操作的时候,我就得回去接着还没洗完的继续洗,但是呢由于我刚才手忙脚乱,把没清洗过的筷子、碗、或者说围裙放错位置了,一时间不知道从哪开始了,那么此刻的我就会选择重新开始在弄一遍,那这样是不是就浪费了我们的时间呀,所以才会需要去把完成的进度进行存档,当我们再次回顾的时候就能方便的知道从哪里开始。
所以上下文它具体指进程在运行过程中,CPU内部的一系列寄存器的值。(而我们的寄存器有很多种,但其中最典型的作用,就是保存当前进程执行的中间结果,包括进程运行到哪一条指令了。这个过程可以分为存档和读档。
**存档:**当进程离开CPU时,就需要把这些寄存器的值保存到PCB的上下文字段中。
**读档:**当进程再次回到CPU进程运行时候,再把PCB中的值恢复到寄存器种。
(d)进程的记账信息
记账信息也就是统计了每个进程,在CPU上执行了多久,(可以作为调度执行的参考依据)。比如说学校需要找一个答题快,准确率高的同学去参加竞赛,此时有两个特别优秀的同学,不好抉择,于是呢学校就出了几道题,要求在最短时间内,并且准确率高的同学获胜,所以此时两个同学相当于两个进程,同时开始做题,然后老师就在旁边记录答题时间,最后判断答案,选取最优的同学。
总结:
操作系统往往使用双向链表这样的结构来阻止PCB:
(1)创建一个进程,就是创建一个链表的节点。
(2)销毁一个进程,就是把链表的节点删除了。
(3)遍历进程列表,就是遍历链表。
(二)、内存分配、内存管理
操作系统对内存资源的分配,采用的是空间模式,也就是说不同进程使用内存中的不同区域,相互之间不会干扰彼此。
操作系统给进程分配的内存,是以“虚拟地址空间”的方式进行分配的,每个进程访问的内存地址,都不是真实的物理内存的地址。
虚拟地址空间:
上面这个图是每个进程都能够直接访问到物理内存的地址,但是会出现问题,当我们代码出现bug的时候,数组下标越界,野指针(该指针指向的地址是不确定,随机的,找不到家的那种)等现象的时候,就很可能导致进程2的内存中的内容出现问题。所以就会对操作系统的“稳定性”产生影响。
为了解决上面的问题,此时页表就出现了,页表它是用来存储逻辑地址和物理地址之间映射的数据结构。如下图,这里访问的内存会被操作系统自动映射到真实的物理内存上,但是进程自身感知不到实际的物理地址是什么。实际操作时0x00~0xff这一段。
所以当出现一些bug的时候,伤害的并不是真正的物理地址,而是需要通过页表去翻译,当发现没有这个地址,那么就无法去修改物理地址,也就不会对别的进程的内存数据造成干扰。
(三)、进程间通信
进程它是操作系统进行资源分配的最小单位,也就是说各个进程之间是无法感受到对方存在的,也就是所说的“隔离性”。但是如果每个进程都可以直接访问我们的物理内存,那么就没有了隔离性,也就不需要进程之间进行通信,直接把进程1的结果写到进程2的内存中就行。所以进程间通信,是在隔离性的前提下,找一个公共的区域让这些进程借助这个区域来完成数据交换。
目前操作系统提供的通信机制有下面几种
1.管道
2.共享内存
3.文件
4.网络
5.信号量
6.信号