文章目录
进程调度
进程调度:控制协调进程对CPU的竞争,即按一定的调度算法从就绪队列中选中一个进程,把CPU的使用权交给被选中的进程。
进程调度算法
- 算法确定的原则:系统性能和效率
- 具有公平性,防止饥饿现象
- 资源利用率,特别是CPU利用率,不希望频繁调度
- 在分时系统中要追求响应时间,其越短越好
- 在批处理系统中要追求系统吞吐量
- 各种进程调度算法
-
先进先出进程调度算法(FIFO)
优点:实现简单
缺点:没考虑进程的优先级
-
时间片轮转法(RR—Round Robin)
把CPU划分成若干时间片,并且按顺序赋给就绪队列中的每一个进程,进程轮流占有CPU。当时间片用完时,即使进程未执行完毕,系统也剥夺该进程的CPU,将该进程排在就绪队列末尾。同时系统选择另一个进程运行。
时间片选择问题:时间片的大小设定至关重要
- 固定时间片:多数微机采用,简单易行
- 可变时间片:可根据进程的优先数来设定时间片的大小
-
基于优先数的调度算法(HPF—Highest Priority First)
优先数大不一定优先级高,要求给每个进程赋予一个优先数,放入PCB中。
-
可抢占式最高优先级算法、不可抢占式最高优先级算法
-
可抢占式 vs 不可抢占式:
可剥夺式(可抢占式):当有比正在运行的进程优先级更高的进程就绪时,系统可强行剥夺正在运行进程的CPU,提供给具有更高优先级的进程使用。
不可剥夺式(不可抢占式):当前进程占用CPU,直到执行完或被阻塞,才让出CPU给另外一个进程。
-
-
确定优先数的方法:
-
静态优先数法:
在进程创建时指定优先数,在进程运行过程中优先数不变
优点:简单,开销较小
缺点:公平性差,可能造成低优先级进程长期等待
-
动态优先数法:
在进程创建时指定一个优先数,但在其生命周期内优先数可以动态变化。eg:等待时间长优先数可变大
优点:具有公平性
缺点:开销较大
-
-
-
多队列反馈调度算法
实现:
(1)将就绪队列分为N级,每个就绪队列分配给不同的时间片
队列级别越高,时间片越小;级别越低,时间片越大;最后一级采用时间片轮转,其他队列采用先进先出;
(2)系统从第一级调度,当第一级为空时,系统转向第二个队列
(3)当运行进程用完一个时间片,放弃CPU时, 进入下一级队列
(4)等待进程被唤醒时,进入原来的就绪队列
(5)当进程第一次就绪时,进入第一级队列
两种占用CPU的方式
-
保证调度:保证每个进程享用CPU时间完全一样
若系统中有n个进程,则每个进程占用 CPU时间为1/n
-
彩票调度:
-
给每个进程发一定数量的彩票,而调度器则从所有彩票机里随机抽取一张彩票, 持有该彩票的进程就获得CPU
-
用户公平调度:按照每个用户来分CPU
(若一个用户的进程多,则其拥有的进程所获得CPU时间较少,反之亦然)
进程调度时机
-
当一个进程运行完毕 or 运行变成等待状态
-
分时系统:时间片到
-
可抢占式:当有一个优先级高的进程就绪
(新产生一个进程、等待变成就绪)
CPU调度过程
-
保存现场:顺序保存,最后一步是保存PSW
-
选择要运行的程序
如果没有就绪进程,系统会安排一个闲逛进程;
没有其它进程时闲逛进程一直运行,在执行过程中可接收中断
-
恢复现场:最后一步恢复PSW
进程通信机制
1. 管道通信机制(一般指无名管道)
管道:连接两个进程之间的一个打开的共享文件,用于进程之间的数据通信。
借助于文件系统机制实现,包括(管道)文件的创建、打开、关闭和读写(读写 进程相互协调)
在使用管道前要建立相应的管道,然后才可使用
-
单向,半双工
-
优点:传送数据量大;简单,无需特殊设计即可进行进程间通信
-
缺点:
-
通信速度慢
-
并不是所有OS支持(UNIX和类UNIX支持);
-
不方便:管道通信需要在相关进程进行(无名管道),或需要知道名字打开使用(命名管道)
-
只能承载无格式字节流
-
-
无名管道 vs 命名管道
无名管道:得到两个文件描述符, 分别用于写和读。
int pipe(int fildes[2]); 文件描述符fildes[0]为读端,fildes[1]为写端; 通过系统调用write和read进行管道的写和读;
– 进程间双向通信,通常需要两个管道;
– 只适用于父子进程之间或父进程安排的各个子进程之间;
2. 命名管道
-
可在两个不相关进程之间进行管道通信
-
FIFO
-
半双工
-
命名管道与文件系统共享一个名字空间,命名管道不得与文件系统中文件重名
3. 信号通信机制
面向需求:用于通知接收进程某个事件已经发生
想迫使一方对我们的通信立即做出回应
不愿意事先建立任何连接,而是临时突然需要向某个进程通信
传输信息量微小,使用管道或套接字不划算
-
定义:通过发送指定信号来通知进程某个异步事件发生,以迫使进程执行 信号处理程序。信号处理完毕后,被中断进程将恢复执行。
-
软中断,传递短消息
-
信号分类:
-
按发送源:
用户、内核和进程均能生成信号请求
eg:Ctrl+C
-
操作系统标准信号、应用进程定义信号
-
-
Linux信号实现机制:数据结构 + 信号的产生和发送 + 信号的检测和处理
-
数据结构
每个进程task_struct结构中signal域专门保存接收到的信号,内核 根据所发生的事件产生相应的信号并发送给接收进程。相当于 “中断请求寄存器”的某位置位 进程task_struct结构中的blocked是信号屏蔽标记,相当于“中断 屏蔽寄存器” 一个进程可以收到多个不同信号,系统仅允许进程每次处理编号最小的一个,其余信号只有在此进程下次调度运行时才被处理 信号处理程序入口存放在task_struct的sigaction[]数组中,信号的编号对应于数组下标,数组元素的值是信号处理程序的入口地址
-
信号的产生和发送
函数sigaction(signo,act,oldact)信号预置处理程序 函数kill(pid,sig)用来向指定进程发送指定信号
-
信号检测和处理流程
-
信号检测与响应发生地点
- 系统空间
-
信号检测与响应发生时间
- 在中断或异常处理程序末尾,在进程从核心态返回用户态之前
- 或在处理运行进程所遇到的时钟中断结束之前
- 或进程以interruptible状态进入等待队列之前(若此时收到信号,就不睡眠)
-
检查处理信号
捕捉信号,执行默认操作,忽略信号
- 系统调用do_signal()检查此进程是否已收到信号,若是则执行handle_signal()让它返回用户态并转入信号处理程序执行
- 信号向量表:通过信号编号查表,从而找到并转入相应的信号处理程序
- 也有屏蔽设施
- 系统调用do_signal()检查此进程是否已收到信号,若是则执行handle_signal()让它返回用户态并转入信号处理程序执行
-
信号处理结束
- 执行系统调用sigreturn()陷入内核,内核做好善后工作后返回用户态,回到应用程序的断点执行
-
-
处理过程与中断的不同:
-
信号完全由软件实现
-
信号接收者必然是一个进程 (相当于CPU)
-
中断向量表和中断处理程序全部位于系统空间
信号向量表处于系统空间 + 但信号处理程序往往由应用程序提供,用户空间执行
-
-
4. 信号量通信机制
-
低级通信机制(因为P、V低级通讯原语)
只能传递简单的信号(解决->采用高级通信原语:共享内存、消息机制)
-
常作为一种锁机制
防止某进程正在访问共享资源时,其他进程也访问该资源
进程间以及同一进程内不同线程之间的同步手段
5.共享主存通信机制
- 定义:相互通信的进程间设有公共内存,一组进程向该公共内存中写,另一组进程从公共内存中读,通过这种方式实现两组进程间的信息交换。
- 需要考虑的问题:
- 怎样提供共享内存:操作系统负责
- 公共内存中的读写互斥问题:程序开发人员负责
- 实现:
- 在主存开辟一个公用存储区
- 要通信的进程把自己的虚地址空间映射到共享主存区
- 发送进程将信息写入共享主存的某个位置时,接收进程可从此位置读取信息
- 优点:最快捷最有效
- 缺点:
- 管理复杂
- 两个进程必须在同一物理主机
- 进程传染病毒
- 与其他通信机制,如信号量,配合使用,来实现进程间的同步和通信
6.消息传递机制—消息队列
大量信息传递的一种高级通信方式
消息是一组信息,由消息头和消息体组成。
- 消息传递机制至少需要提供两条原语send 和receive
前者向一个给定的目标发送一个消息,后者则从一个给定
的源接受一条消息。
- 如果没有消息可用,则接收者可能阻塞直到一条消息到达,
或者也可以立即返回,并带回一个错误码- 消息传递方式的变种很多
- 直接通信(消息缓冲区)
- 间接通信(信箱)
与管道的区别
管道 | 消息传递机制 | |
---|---|---|
读写进程 | 固定的读写进程 | 无需固定的读写进程,任何有权限的进程都可 |
通信进程数量 | 点对点 | 多个进程可以读写消息队列,多对多 |
实现底层区域 | 只在内存中实现 | |
通用性 | 仅UNIX和类UNIX系统 | 几乎所有主流操作系统均支持消息机制 |
消息队列
消息的链表,存放在内核中并由消息队列标识符标识
-
优点:
- 信息量大
- 承载多种数据格式
-
实现:(有界缓冲区原理)
- 在操作系统空间设置一组缓冲区;系统为进程提供了两个高级通讯原语send和receive
- 发送进程需要发送消息:
- 执行send系统调用,产生自愿性中断,进入操作系统,操作系统为发送进程分配一个空缓冲区
- 并将所发送的消息从发送进程copy到缓冲区中,然后将该载有消息的缓冲区连接到接收进程的消息链链尾
- 发送进程返回到用户态继续执行
- 在以后某个时刻,接收进程执行到receive接收原语:
- 产生自愿性中断进入操作系统,由操作系统将载有消息的缓冲区从消息链中取出,
- 并把消息内容copy到接收进程空间
- 收回缓冲区,接收进程返回到用户态继续进行
消息队列的操作是临界区
-
消息缓冲区结构:
消息长度、消息正文、发送者、消息队列指针 -
消息队列首指针m_q保存在PCB中
- 互斥信号量m_mutex,初值为1,用于互斥访问消息队列,在PCB中设置
- 同步信号量m_syn,初值为0,用于消息计数,在PCB中设置
消息队列不随创建它的进程的终止而自动撤销,必须用msgctl(msgqid, IPC_RMID, 0)。另外,msgget获得消息队列ID之后,fork创建子进程,在子进程中能继承该消息队列ID而不必再一次msgget
7. 套接字
面向客户-服务器模式设计
- TCP/IP网络通信的基本构件之一,必须有客户端和服务器端两个进程
-
双向的
-
数据格式:
字节流(一对一)、报文(多对一,一对多)
-
主要用于网络通信
通信过程:
- 服务器方先创建一个服务器套接字,然后在该套接字上监听,等待远方的连接请求
- 客户创建一个客户套接字,向服务区套接字发送连接请求
- 服务器套接字收到连接请求后,将在服务器机器上创建一个客户套接字,与远方客户机上的客户套接字形成点到点的通信
- 客户端与服务器端通过send和recv命令在所创建的套接字上进行交流