!:进程的控制和描述
*进程的定义:进程是一个具有独立功能的程序在一个数据集合上的一次动态运行过程(是操作系统进行调度和资源分配的基本单元,进程间的通信、同步及上下文切换的开销略大)
*进程的特征(了解)
1.动态性:动态性是相对于程序本身来说的,程序仅仅是存放在硬盘上的代码,而进程是程序在某一特定数据集上的动态运行,所以,动态性是程序的最基本特性
2.并发性:并发性是指在一段时间内,操作系统内有多个进程并发执行
3.独立性:进程之间是相对独立的,每个进程都有可用的内存空间
4.异步性:即进程之间的运行是按照异步的方式运行的,即每个进程都各自独立的以不可预知的运行速度向前推进
*进程的状态
1.三态:就绪态、阻塞态、运行态
2.五态:初始态、就绪态、阻塞态、运行态、终结态
3.七态:初始态、活动阻塞、静止阻塞(挂起后)、活动就绪、静止就绪(挂起后)、运行态、终结态
*进程的挂起
进程停止运行,并且从内存中换出到硬盘
进程的挂起可能的原因有:程序中内存的确不够用了,要换出内存中的一些内容;操作系统负荷调节,如果操作系统不挂起一些程序的话,系统可能不能正常运行了;父进程请求的,可能是为了进行进程间同步;终端用户请求的等等
*进程管理中的数据结构
1.PCB(Process Control Block)进程控制块:用来描述进程状态信息及运行过程的数据结构,是表示进程存在的唯一标识,进程管理也就变成了PCB管理
2.进程控制块中主要有四方面的内容:进程标志符信息;处理机状态(处理机上下文);进程调度信息(进程状态及优先级信息等);进程控制信息(进程间同步和通信的信号量等)
*进程控制
1.Unix内部进程的组织是按照树形结构组织的,但是在Windows内部不存在任何进程层次结构的概念,所有的进程都具有相同的地位。
2.可能引起进程创建的事件:用户登录、进程自己请求创建一个子进程等
3.可能引起进程终结的事件:正常结束、进程自己因为执行中发生了异常自己死了或者被操作系统杀死了、或者并没有发生什么被父进程或者操作系统给杀死了
*进程同步
1.利用信号量机制进行同步:进程中使用信号量和在Java并发编程中使用Semaphore类进行线程间同步类似,通过对信号量所持有的许可证的数量的操作实现进程间同步
2.利用管程进行同步:系统中各种硬件资源及软件资源都可以用数据结构抽象的描述其资源特性,即用少量的信息和对该资源执行的操作来表征该资源,而忽略他们的内部实现细节,因此利用共享数据结构抽象的表示系统中的共享资源,并将对该数据结构实施的特定操作定义为一组过程。进程必须通过操作这组过程来间接地操作共享资源。
*进程通信
进程通信的类型:
*共享存储器系统(Shared-Memory System):在共享存储器系统中,相互通信的进程共享某些数据结构或者共享存储区,进程之间能够通过这些空间进行通信
*管道通信系统(Pipe):所谓管道是一个连接了写进程和读进程的一个共享文件,又叫管道文件,写进程把数据写进管道文件,读进程从管道文件中读数据出来以实现进程间通信
*消息传递系统(Message passing System):在该机制中,进程通信并不借助于任何的共享数据结构共享存储区共享文件什么的,而是以格式化的消息为单位,把要通信的数据封装在消息中,并利用操作系统提供的一组进程间通信命令(原语)进行进程间通信
*客户机-服务器系统(Client-Server System):通过套接字、远程工程调用、远程方法调用等实现远程通信
!:线程
*线程的定义:线程是进程的一条执行路径,是比进程更小的执行单元,是CPU调度的基本单位,同一进程的不同线程间共享同一地址空间,于是呢,线程间的通信同步及上下文切换的开销要比进程小很多了,另外,创建一个线程比创建一个线程的开销也小很多
*对于线程的创建、同步、通信,Java程序设计语言提供了一组详细而功能强大的基础类库及高级工具类库,可以方便的进行多线程并发编程(也可以使用Fork/Join框架利用多核处理机进行并行编程)
!:处理机调度与死锁
*处理机(CPU)调度的层次
1.高级调度:又叫长程调度或者作业调度,是将程序从硬盘加载到内存并进行初始化,可能的话还要将初始化后的进程加入到就绪队列中去
2.中级调度:又叫内存调度,由于使用了虚拟存储器技术,很多进程由于可能的各种原因被挂起到了硬盘中,中级调度就是把这些挂起到硬盘中的进程重新调度到内存中去
3.低级调度:又叫短程调度或者进程调度,是利用某种调度算法,从处于就绪队列中的进程中挑一个出来,并分配给其处理机资源
*处理机调度算法的目标
不同的操作系统由于其使用场景和要求不同,其处理机调度算法的目标也不同,但有一个共同的目标就是:尽可能提高处理机的利用率
*进程调度的任务
1.保存上一个进程处理的处理机现场
2.根据某种调度算法选择下一个要处理的进程
3.分配处理机给这个选中的进程,开始处理
*进程调度的方式
1.非抢占式:当一个进程分配了处理机之后,该进程的执行就不能被打断了,直到该进程主动放弃,要么正常结束,要么其他原因主动放弃了处理机。有很大的问题就是:处理机的利用率特别低,因为其他硬件资源的运行速度总是低于处理机,不免频繁发生等待,导致处理机的利用率特别低
2.抢占式:这种方式允许进程间抢占处理机资源,当然抢占并不是乱抢,而是有一定原则的:优先权原则(允许优先级高的进程抢占优先级低的进程的处理机执行权)、短进程优先原则(允许新到的短进程可以抢占长进程的处理机执行权)、时间片原则(各就绪进程之间按照时间片轮询的机制获得处理器资源,当前进程运行的时间片到了便让出处理机,并交由处理机重新调度)
*进程调度算法
0.进程调度调度算法主要是针对抢占式调度方式的,大致的就是根据抢占式的几个原则实现的调度算法以及在这些算法的基础上进行了升级
1.轮转调度算法(Round Robin):该算法使用了非常公平的处理机分配方式,每个进程每次占用处理机的时间仅仅是一个时间片。在RR算法,系统将所有就绪进程按照FCFS(First Come,First Served:先来先服务)组成就绪队列,然后按照RR进程时间片分配
2.优先级调度算法:一般用于要求实时性要求较高的系统中。当有较高优先级的进程新到时可以抢占优先级较低的进程的处理机。通常进程有两个优先级:静态优先级(进程本身就有的)、动态优先级(在进程运行的过程中,进程的优先级根据进程的推进不断改变,以便获得更好的调度性能)
3.多队列调度算法:主要用于多处理器系统中。针对不同的处理机维护一个不同的就绪队列,每个就绪队列可以采用不同的调度算法,以适应系统的要求
4.多级反馈队列调度算法(Multileved feedback queue):是目前认为的一种比较好的进程调度算法。基本描述为:使用多个就绪队列,每个队列被赋予不同的优先级。第一队列优先级最高,第二次之,其余队列优先级逐个降低。这是其一。其二,不同优先级队列分配的时间片也不同,优先级越高时间片越长。队列之间采用优先级调度算法,队列之内采用FCFS先来先服务的调度算法。新的进程到来之后,首先放到第一队列,如果在第一队列中没有执行完,OK,放到第二队列末尾进程等待,依次下去,到了最后一个队列之后,还没有执行完,就使用RR轮转调度算法进行调度了
*死锁的处理
1.处理方法
1.1预防死锁:大致是在代码级别进行死锁的预防
1.2避免死锁:不同于预防死锁,是在进程执行过程中,使用一定的算法避免死锁的发生,因为即使进程内部没有发生死锁,也可能因为进程之间操作共享资源造成死锁,这就要操作系统费心了。常见的有银行家算法
1.3检测死锁:并不是采取措施避免死锁的发生,而是允许死锁的发生,但可通过检测机构及时地检测出来死锁的发生,然后采取响应的措施,把进程从死锁中解救出来
1.4解除死锁:显然死锁已经发生了,不得不把相关进程从死锁中解脱出来。常见的可以有:取消一些进程,回收他们的资源,解除死锁。
2.避免死锁:在进程运行过程中,OS要采取一定的措施(算法)避免死锁
*银行家算法:因为最初这个算法是为银行贷款设计的,后来引用到操作系统中的,所以就交了银行家算法
1.OK,首先有四个数据结构:
Max矩阵(表示每个进程所需的每个资源的最大数量),譬如下表:P0进程所需A类资源的最大数量是7个,B类5个,C类3个
Allocation矩阵(表示每个进程已经获得的资源的数量),譬如下表:P0进程所需的A类资源已经获得了0个,B类1个,C类0个
Need矩阵(表示每个进程现在还需要的资源的数量),值等于所需减去所得
Available矩阵(表示现在可用空闲资源的数量),每个阶段都只有一个组值
2.银行家算法的描述:
Step1(资源尝试性分配):如果一个进程发出了资源请求,如果其请求的资源大于所需资源,OK,报错,不改求这么多呀,如果不多,OK,看空闲资源够不够,如果不够,则让他等待,如果够了,则分配,响应的数据结构做响应的改变
Step2(安全性检查):资源分配之后,要做安全性检查,就是,我如果这么分了,所有的进程能不能相安无事的执行完成呢?那就要看能不能找出一个资源分配的进程顺序,而这个分配顺序能够使进程正常地完成。大致如下:譬如一个进程按照第一步分配了资源,接下来进行安全性检查,具体是根据Available矩阵中还有多少可用的资源进行分配,找到一个能满足分配的进程,把资源分配给他,然后回收他的资源,更新Available矩阵,接着往下找,直到所有的进程都能够得到资源执行完,表示OK,这次资源分配是安全的,则把资源分配给这个进程的资源请求;否则,则表示当前进程请求的资源如果分配了,系统出于不安全状态,不分配。