操作系统——虚拟机,进程,线程

虚拟机的必要性:

操作系统是唯一的程序,在操作系统上运行多个进程,操作系统分配硬件和软件资源;当多个进程运行在一个操作系统上时,由于指针等问题,此进程可能会影响另一进程的数据安全,是不安全的,操作系统获得硬件的大小是根据其下进程的要求来的,同一操作系统下不同进程是共享内存资源的,因此如果有不同的操作系统,两个在不同操作系统下运行的进程就不会共享内存资源了,这就引出了虚拟机;

虚拟机管理程序(VMM):将总的硬件资源划分为多个部分,这样就形成了仿佛有多个物理机器的假象;操作系统只能分配已经获得的硬件资源,因此不同操作系统下的进程相互之间是不会干扰的;主要作用是分配硬件资源;

第一类VMM:运行在硬件上;只有VMM可以使用特权指令,操作系统和进程都是在用户态运行的;

VMM运行在内核态;

虚拟机管理程序相当于拆分的操作系统,

第二类:运行在宿主操作系统上,可迁移性更好,可在不同操作系统上应用,相当于一个大软件,里面有许多功能,相当于把一个电脑的功能全部迁移到另一个电脑上 ,第一类不可以;第二类分配的资源可能是离散的,同时性能更差,

虚拟机特权指令:将特权指令层级化,加快运行速度的同时保证安全;

中断的意义:如同输出设备一样,程序从内存中取地址的速度要高于IO设备处理数据的速度,为提高效率采用了中断,中断是一种消息传递,

进程:

程序:静态的,存放在磁盘里的可执行文件,实际上是一系列的指令集合;

进程:动态的,程序的一次执行过程;

qq是一个程序,不同的qq进程是打开了多个qq程序;他们是不同的进程,

线程是最小的程序,划分成线程更好;但不同线程之间应该具有优先级,

PID:区分不同进程的数据结构;是进程的身份证;

进程将在内存中占据一定的空间,获得一些CPU的时间片,这些都根据进程的优先级来,

所有的信息被放在PCB中,PCB是一种数据结构;操作系统所需要的所有信息都被放在PCB中,他是PCB存在的唯一标志,进程被创建时操作系统将会为他创建PCB,操作系统根据PCB进行各种进程的切换,硬件资源的划分等,PCB可能会使用数组,

进程的组成:PCB,程序段(指令段),数据段(产生的数据),

进程控制:

实现进程的状态转换,包括运行态,阻塞态,

进程的状态转换使用原语程序:该程序不能被中断;

使用就绪队列,阻塞队列来实现切换;这里考察链表的插入删除;                                                                                                                                                                                    

原语通过特权指令来实现原子性;

进程通信:消息传递(依靠特权指令,以及特定数据结构),共享存储(开辟存储区,对于存储区的访问必须是互斥的),管道通信(固定的两个进程间,根据管道内信息情况,读进程,写进程会陷入就绪态和阻塞态多种模式)

进程的通信需要特权指令 ;

锁的来历:

基于存储区的共享:共享存储;使用相关接口映射到进程本身的内存地址上;但是多个进程不能同时访问共享存储区,需要互斥访问,如何保证互斥呢?答案就是锁!

基于存储区的共享:共享存储区开辟后,如何读写是由进程本身来决定的,而不是操作系统,这种共享方式速度很快,是一种高级通信方式;

基于数据结构的共享:类似于全局变量,共享空间里存放的数据类型是固定的,不同的进程只能以特定的方式进行读取,速度慢,限制多,是一种低级通信方式;如int a[3],那么不同进程只能按int的方式来读取;

消息通信:包括直接通信和间接通信,直接通信依靠原语以及消息队列进行信息传递,

指名道姓;间接通信依靠内核区的特定空间作为传递中介;消息的发出和接收都需要特权指令;

管道通信:本质上是循环队列和缓冲区,写进程以缓冲区的形式看待管道,读进程以循环队列的形式看待管道;

各个进程对于管道的访问是互斥的;管道的大小是固定的,因此管道写满时,写进程将阻塞,直到读进程将数据取走,当管道为空时,读进程将阻塞,直到写进程往管道里写数据;才能唤醒读进程;管道是栈区,读完该区域内变量就会改变,因此同一信息不能多次读写,只能一次;

线程:

线程是CPU调度的基本单位,线程是轻量级进程,

用户级线程;

调度:根据优先级决定那个线程被调度,需要采用优先队列,大根堆小根堆的数据结构;但应该是链表的存储方式;

作业:一个具体的任务,创建一个进程

线程的运行队列需要使用循环队列;

高级调度:按一定的原则从后备队列中选择一个作业调入内存,创建进程;

根据进程的起点终点分为:

高级调度(外存调入内存),创建态到就绪态;

低级调度(内存到CPU),就绪态到运行态;

中级调度(暂时在外存中的到内存):就绪到就绪挂起态,阻塞到阻塞挂起,挂起的意思是进程被挪到外存中,当计算机内存资源不足时,需要把某些优先级低的进程调出内存,暂时安排在外存中,等内存空闲时在调入内存,暂时调到外存后进程状态为挂起状态,中级调度的频率比高级调度 要高,

 

 作业:进程的前身,进程是在内存中有确定地址的指令集合,包括PCB,代码段,数据段,位置在内存中;而作业是在外存中的,只有被操作系统放到内存中才成为进程;作业并不是一经创建就成为进程的,而是在外存中形成作业队列(因此需要一个特殊的外存空间来储存这个队列,这样操作系统才能在指定的区域内读取作业队列),操作系统根据优先级(堆的数据结构)来选择某个作业进入内存,再分配了空间创建PCB后,作业成为内存;

进程的调度方式:高级调度,中级调度,低级调度;

高级调度:创建态->就绪态;外存->内存,将作业后备队列里的某个作业由外存放到内存中,创建为进程;

低级调度:就绪态->运行态,内存->CPU,就绪队列里的进程获得CPU的时间片,进入运行态,

中级调度:挂起态->就绪态,外存->内存,当内存空间不足时,某些进程或作业无法被放入内存,其代码段,数据段以及PCB将被映射到外存中,进入挂起态,等到内存足够时才被调入内存。

进程的调度就是为了进程的状态转换;

进程调度的时机:

特权指令相关的操作是不能进行进程切换(调度)的,除此之外都可以;

当进程访问了一些特殊的资源时,进程的调度可能不能顺利的进行,比如当进程访问了就绪队列时,由于非进程内存是共享资源,就绪队列所在内存区将会被上锁,那么此时进程的调度就无法进行,只有该进程访问结束后才能;进程的切换是相关数据结构的插入删除操作,因此别的资源被上锁时不会出现这种情况;

上段话说:进程在操作系统内核临界区中不能进行进程调度,切换;

临界资源:一个时间段内只能互斥访问的资源,称为临界资源;临界区就是访问临界资源的代码区,

进程切换与锁:除了操作系统内核临界区外都可以被进行调度;

操作系统内核临界区不能进行调度与切换,但一般进程处于临界区时是可以进行切换的,如某进程访问打印机,打印机属于临界资源,该切换也要切换,但内核程序临界区则不能切换;这里说的切换是指该临界区进程,即当进程处于临界区时是可以被切换的,但切换后仍然保留锁,但是内核临界区是不能被切换的,

进程的切换:一个进程让出CPU,另一个进程占用CPU,

 

进程切换完成的动作:

1.原来进程的PCB保存;

2.新进程的PCB恢复;

因此进程的切换是有代价的,过于频繁的进行进程的切换会使整个系统的效率降低;使得系统大部分时间都花在了进程的切换上,真正用于执行进程的时间减少;

注意:进程调度是相关就绪队列的插入删除操作,只有进程的切换才会让进程运行;

调度程序:

操作系统内专门的程序模块来处理进程的调度与切换;

让谁运行——调度算法;运行多长时间?——时间片大小;

闲逛进程:休眠时的运行进程,不进行任何读写访问操作,

调度算法:

先来先服务;短作业优先;高响应比优先;

针对单个进程的效率计算:        周转时间:完成时间-到达时间;

                         带权周转时间:周转时间/运行时间;//周转时间比运行时间大多少倍;

                        等待时间:周转时间-运行时间;

先来先服务(FCFS)

算法类型:非抢占式算法;

优点:算法实现简单,

缺点:对于短作业来说带权周转时间太大,体验不好;对长作业不利,短作业有利;

是否会导致饥饿:不会;

适用于非抢占式调度,按一般队列来;

短作业优先(SJF)

追求最少平均等待时间,最少的平均周转时间,最少的平均带权周转时间;

非抢占式算法;   

高响应比优先(HRRN)


进程的并发性导致异步性,各进程以独立的不可预知的速度向前推进,当涉及到对共享资源的访问时,为了解决问题,就出现了锁,一个进程会对共享资源上锁,在进程完成前别的进程不能访问共享资源;共享资源包括数据库,内存空间,播放器;显示器;

共享包括:互斥共享方式,同时共享方式;

把一个时间段内只允许一个进程使用的资源称为临界资源,许多物理设备,数据,变量,内存缓冲区都属于临界资源;对临界资源的访问必须互斥的进行,只有某进程释放临界资源,另一个进程才能访问临界资源;

死锁的前提:进程在完成进入区上锁后,无法执行临界区,此时是否需要解锁?

互斥原则:

1.临界区空闲时,允许其他进入临界区的进程立即进入;

2.忙则等待;

3.优先等待;(不能饥饿)

4.当进程无法进入临界区时,应该立即释放处理机,


进程互斥的实现方法:全局变量来传递信息;包括bool数组和bool值;数组值表示自己是否访问临界区,int值则表示系统允许访问临界区的进程名,只有本进程允许加上系统允许,才能让系统允许进程访问临界区,上锁阶段的代码执行上锁和检查两个操作;

单标志法:使用一个全局变量,根据全局变量的值来决定进程是否访问临界区;缺点:容易造成系统浪费,违反了空闲让进的原则;

双标志检查法:违反了忙则等待的原则;

双标志后检查法:两个都是true,导致都不能访问了;饥饿

皮特森算法:

三个算法都无法实现让权等待的原则,即不会放弃CPU资源;


原语用关中断指令防止切换,关中断指令不适用于多处理机,只适用于操作系统内核进程,

TestAndSet指令

使用硬件实现,执行过程中不能被中断,只能一气呵成;

线程的理解:一个程序出现了若干个子程序,同时运行,也就在此时全局变量,变得有意义;这些子程序最后都在一个main()函数中;操作系统相当于一个大的程序;使用操作系统的全局变量(在堆区,静态区等的变量,)

进程互斥:锁:一个Bool的全局变量;

软件实现互斥的方法:将两个进程的代码交替的写在一起就会发现问题!

硬件实现互斥的方法:

中断屏蔽法:将每个进程访问临界区的代码设置为原语,即不被CPU中断,相应的也就不会出现进程切换;

缺点:不适用于多核处理机,只适用于操作系统内核进程,不适用于用户进程(如果用户进程删去了关中断指令,那么CPU将永远不会发生进程切换);

TestAndSet指令:

TSL指令使用

信号量:信号量是一个变量表示系统中某种资源的数量,如系统中有一台打印机,可以设置一个初值为1的信号量;信号量还可以是更复杂的记录型变量;

注:信号量属于不能随意更改的量,因此它是私有的,只能通过接口进行修改,这种接口是原语,分为wait(S),signal(S);

整形信号量:用一个整数型变量作为信号量,用来表示系统中某种资源的数量;

与普通整数变量的区别:对信号量的操作只有三种,初始化,P操作,V操作;即面向对象经过封装过的整型变量;整形信号量上锁的极值:

缺点:循环消耗时间;不满足让权等待的原则;除此之外进程之间没有优先级;

int S=1;//初始化信号量;表示当前系统中的打印机资源数;

void wait(int S)//wait原语,相当于进入区
{
while(S<=0);
S-=1;
}

void signal(int S)//signal 原语,相当于退出区
{
S+=1;
}

记录型信号量:

//记录型信号量;
struct semaphore{
int value;//剩余资源数;
struct process*L;//该资源的阻塞队列;

};

阻塞队列,就绪队列,有两个原语将进程放入阻塞和就绪队列中,

归纳:记录型信号量确保了信号量的源于操作而且遵守了让全等待的原则;

用信号量机制实现进程互斥,同步,前驱关系:

信号量完美展现了面向对象的设计原则,对数据的保护,通过权限和接口来实现;

信号量关键活动:

1.划定代码中的临界区;

2.设置互斥信号量mutex,初始化;

3.在进入区P(mutex)申请资源,若申请失败将进程移入阻塞队列;

4.在退出区V(mutex)释放资源,将阻塞态中的进程移入就绪态;等待运行;

5.P,V操作必须成对出现。


  1.  进程同步:各并发进程按要求有序进行;让本来异步并发的进程相互配合有序推进;

举例:由于某些原因,P2的5,6指令必须在P1的1,2指令完成后才能执行,那么我们就必须保证1,2在5执行前完成;

p1(){
1
2
3
4


}

P2(){
5
6
7
8
}

 方法一:p1给p2解锁;方法就是p2在指令2完成后进入就绪态,之前都是阻塞态,阻塞态到就绪态的转换使用V操作

 方法二信号量机制实现前驱关系:有时一件事情的发生需要多个事情做基础,在计算机中就是一个进程的发生需要多个进程的发生,即图的关系;

多个信号量机制相结合;

 

读者写者问题:

有读者进程和写者进程两组并发进程共享一个文件,当两个或两个以上的读进程同时访问数据时不糊产生副作用,但写进程和其他进程同时访问数据时会导致数据不一致的错误;因此要求:

1.允许多个读进程同时对文件进行操作;

2.只允许一个写进程往文件中写信息,

3.写进程完成写操作之前不允许其他读写操作;

4.写进程执行操作前,所有的读写进程全部退出(完成);

读者进程与消费者进程 不同:读者进程不会改变数据;因此多个读进程可以同时访问共享数据;

写进程必须再其他进程结束访问后才能在临界区进行写操作;

互斥关系:写进程-写进程;写进程-读进程;

读进程与读进程不存在互斥关系

semphore rw=1;//临界区的信号量;实现对共享文件的互斥访问;

int cnt=0;//记录当前有几个读进程在访问文件;

semphore mutex=1//用于保证对count变量的互斥访问;

semaphore w=1;//用于实现写优先;

写进程:

writer(){

while(1)

{

P(rw);//对rw上锁;

写文件;

V(rw);//解锁

}

}

读进程:

reader(){

while(1)

{

P(mutex);

if(cnt==0)

P(rw);//上锁;

cnt++:

V(mutex);

读文件;

P(mutex);

cnt--;

if(cnt==0)

V(rw);//解锁

V(mutex);

}}

P,V操作会将相关进程插入或移出就绪或阻塞队列;如果cnt!=0,读进程将直接访问临界区;这没有问题;

潜在的问题:只要读进程还在读,写进程就要一致阻塞等待,可能“饿死”,因此这种算法中,读进程时优先的;

李治军操作系统

BIOS 采用汇编的好处:可以严格控制内存,可以严格读取确定地址处的内容,C语言做不到。

开机第一件事:(关注CS:IP指向哪里,CPU执行什么命令)

1.CS,IP指向ROM BIOS映射区,执行指令,先检查硬件,RAM,

2.之后将磁盘0磁道0扇区(的内容,供512个字节)读入0x7c00处,设置CS=0x070c,ip=0x0000;CPU开始执行;改扇区称为引导扇区;

读取过程:

引导扇区的代码:

读取第一步:关注start:1~4行设置ds:di,es:si的地址,rep movw将引导区的代码挪动到内存的一个地址处(es:di处),此后继续顺序执行改代码,但由于挪动了位置(原本执行的地址在BIOS区,现在在es:di处,同样的代码,但不在一个位置了),因此使用jmpi go,INITSEG修改CS:IP的值,保证继续向下执行;

读取第二部:继续读取:关注从哪读取,读多少,读到哪,读完干什么?

从cl开始读,读到ex:bx;读多少呢(ax)al是扇区个数,cl是开始扇区,即将set-up的四个扇区读到ex:bx上,是第一步读取的上边。读完后引发中断,int 0x13.

打印LOGO:显示窗口,涉及到操纵显示器.

读如System模块;

以上命令都是在boot扇区内的命令,之后计算机将执行set-up扇区的指令,

总结

检查硬件,将操作系统读入内存内——这些指令都在BIOS内,因此开机后,将执行BIOS里的指令,完成后开始执行操作系统,命令包括:

检查硬件,读入操作系统代码(将set-up,system模块读入内存,之后执行set-up的命令,)打印LOGO四大部分。

可以看到分成了若干个进程,采用int中断指令来实现。

开机第二件事:执行setup模块的内容(操作系统的代码了)

set-up内容:完成信息的初始化,并改变操作系统的位置到0地址处,此后不再改变位置;并进入保护模式

start:读取信息,如读入内存的大小以方便管理内存,该值放在0x90002处;除此之外还有显卡啊参数,光标位置。

内存有多大:

int 0x15中断指令将获得物理内存的大小;获取的值放在ds:2处;ds的值在第一行得到。最终放在0x90002处,

do-move:将system模块(操作系统代码)移动到0地址处,这也是为什么一开始在0x90000处放置set-up模块。

mov ax,1;mov cr0,ax:切换到保护模式,由16位模式切换到32位模式;

此时CS的值相当于哈希表里的键,在GDT表里查到真正的基址,之后偏移与IP相加形成真正的地址;GDT表使用硬件电路实现。

GDT表由set-up完成,此后寻址,中断命令地址的寻址方式都发生了改变;都变成了查表。

System模块

P6 

 head.s跳转到main.c,

第一行进行压栈压入main.c的参数,第二行压入操作系统的main.c,之后跳转到set_paging,进行操作系统数据结构的初始化操作,该指令结束后操作系统开始执行,如果main.结束,将执行L6:死循环,因此main.c不会结束。

 main.c的指令,最后一句如果申请进程失败,将返回。

mem_init,实行内存的初始化,初始化mem_map[]数组,mem_map[]数组表示内存页使用情况,0表示没有使用,每一页是4kb,因此每次>>12,end_mem来自于0x90002的数值。

最终

从开机到操作系统开始执行,需要经历:

boot->setup->head.s->main.c->mem.init四大过程,分别完成操作系统读入内存,初始化,保护模式切换,初始化等事件。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值