操作系统笔记 第二章 进程控制与同步

2.2 进程控制

进程控制的基本过程:

进程的创建
进程的终止
进程的阻塞与唤醒
进程的挂起和激活

系统中运行的进程并不都是孤立的,有的进程运行后,会调用其他进程来执行,这样就组成了进程间的父子关系。
1.进程的创建

1)一个进程创建另一进程的事件(原因)

用户登录:分时情况下用户的请求
作业调度:批处理中
提供服务:运行中的用户程序提出功能请求,要创建服务进程(如打印服务)
应用请求:应用程序自己创建进程,完成特定功能的新进程。(木马程序)

2)创建过程

(1) 申请空白PCB
(2) 为新进程分配资源
	主要是内存资源的处理
(3) 初始化进程控制块
	标识符(包括父进程的)、程序计数器指向程序入口地址,就绪态、优先级等信息的填写。
(4) 将新进程插入就绪队列

原语是由若干指令构成的原子操作过程,作为整体实现功能,不可被打断。

2.进程的终止

1)引起进程终止的事件

正常结束
异常结束
- 内存越界错误
- 保护错(权限错,如修改只读文件等)
- 非法指令(不存在的指令,程序异常转向而把数据当指令)
- 特权指令错(用户态程序试图执行只有OS可执行的指	令)
- 运行超时、运算错、i/o故障等
外界干预
- 操作员或操作系统干预(死锁时,可人为结束)
- 父进程请求终止子进程
- 父进程终止,子孙进程也跟着终止

2)终止过程

对上述事件,OS调用内核终止原语,执行下列过程:
(1) 根据进程标示符,检索出该进程PCB,读其状态。
   *IF 执行态,立即终止该进程,置调度标志为真,指示重新进行调度。
   *IF 有子孙进程,亦应予以终止,以防成为不可控进程。
(2) 归还全部资源至其父进程或系统。
(3) 将该进程PCB从所在队列或链表中移出。

3.进程的阻塞与唤醒

1)引起进程阻塞和唤醒的事件

请求系统服务的满足情况
启动某种需等待(I/O)操作
合作需要的新数据尚未到达
执行某功能的进程暂时无新工作可做(如发送数据进程)

2)阻塞和唤醒过程

由进程调用阻塞原语阻塞自己,是主动行为:
(1)将PCB中的状态改为阻塞
(2)该PCB加入到阻塞队列中
(3)转进程调度,将处理机分配给另一进程
(4)进行进程切换,即根据两切换进程的PCB,保护与重新设置处理机状态。

阻塞与唤醒原语作用相反,成对使用

阻塞进程等待的事件发生时,有关进程(如放弃该资源的进程)调用唤醒原语把等待该事件的进程唤醒。
(1)把阻塞进程从等待该事件的阻塞队列中移出
(2)将其PCB中的现行状态改为就绪
(3)将PCB插入到就绪队列中。

4.进程的挂起与激活

 挂起原语将指定进程或阻塞进程挂起。
(1)检查被挂起进程的状态,活动就绪则改为静止就绪,活动阻塞则改为静止阻塞
(2)将该PCB复制到内存(方便检查)/外存(对换)指定区域
(3)*若挂起的进程是执行态,则需重新进行进程调度。

2.3 进程同步

1. 理解同步的含义

两种制约关系:

  • 间接相互制约关系:主要源于资源共享,表现为
    进程A—打印机资源—进程B(互斥)
  • 直接相互制约关系:主要源于进程合作,表现为
    进程A写缓冲—进程B读缓冲(有序)

进程同步的基本概念

 1)进程同步的主要任务:
	 使并发执行的诸进程之间能有效地共享资源和相互合作,从而使程序的执行具有可再现性。
 2)临界资源
	一次仅允许一个进程使用的资源。
3)临界区
 	每个进程中访问临界资源的那段代码叫临界区。
4)同步机制应遵循的规则
	实现互斥的方法应符合如下每条原则
		空闲让进:资源使用最基本原则
		忙则等待:保证互斥
		有限等待:合适时被唤醒防止死等
		让权等待:能主动释放CPU防止忙等

理解同步

- 互斥:在操作系统中,当一个进程进入临界区使用临界资源时,另一个进程必须等待,直到占用临界资源的进程退出临界区,我们称进程之间的这种相互制约关系为“互斥”。
- 同步:多个相互合作的进程,在一些关键点上可能需要互相等待或互相交换信息,这种相互制约关系称为进程同步关系。可理解为“有序”。

①关中断

进入锁测试前关闭中断,直到完成锁测试并上锁后才能打开中断。进程在临界区执行期间,系统不响应中断,从而不引发调度。
缺点:
- 滥用风险
- 关中断时间过长会影响效率,限制CPU交叉执行能力
- 不适用于多CPU系统

②Test-and-Set指令

boolean TS(boolean *lock)
{
	Boolean old;
	old=*lock;
	*lock=TRUE;
	return old;
}
*一个不可分割的原语

为一个临界资源设置一布尔变量lock,初值为false

do{
   …
   while TS(&lock)  ;
   critical section;
   lock=FALSE;
   remainder section;
}while(TRUE);

③利用Swap指令实现进程互斥
对换指令(intel 80x86中称XCHG指令),用于交换两个字节的内容

void swap(boolean *a, boolean *b)
{boolean temp;
  temp=*a;
  *a=*b;
  *b=temp;	
}

为临界资源设置一个全局布尔变量lock=false。每个进程一个局部布尔变量key。

do{
    key=TRUE;
    do{
     swap(&lock,&key);
}while(key!=FALSE);
     临界区操作;
     lock=FALSE;
     剩余区;
}while(TRUE);

2. 信号量机制控制进程同步

1) 整型信号量

最初的信号量机制,两个原子操作对一个共享整型量进行操作。

  • 信号量定义为一个整型量;
  • 根据初始情况赋相应的值;
  • 仅能通过两个原子操作来访问。

在这里插入图片描述
2)记录型信号量

  • 整型信号量符合“有限等待”原则

      signal释放资源后,当CPU被分配给等待进程						  后,等待进程仍可继续执行,可以符合“有限等待”。
    
  • 但整型信号量不符合“让权等待”原则

      - 整型信号量的wait操作,当s ≤0时,当前进程会占着CPU不断测试;
      - 信号量原语不能被打断,这个占有CPU的进程会一直不断的占据CPU循环下去,陷入忙等。
    

不仅要有值的处理,还有队列的处理。
此时形成记录型数据结构,包括两部分:

  • 整型变量value(代表资源数目)

  • 进程链表L(链接所有等待进程):

    代码描述:

    type  Semaphore=record
      	value:integer;
      	L:list  of  PCB;
      end; 
    

    操作:S.Value,S.L
    在这里插入图片描述

定义信号量semaphore代表可用资源实体的数量。又叫信号灯。
- 当≥0,代表可供并发进程使用的资源实体数
- 当<0,表示正在等待使用该资源的进程数。

建立一个信号量必须经过说明,包括

  • 信号量所代表的意义
  • 赋初值
  • 建立相应的数据结构,以便指向等待使用临界区的进程。

除初值外,信号量的值仅能由标准原子操作P、V操作来改变。 PV操作是荷兰语通过和释放的意思。

3)信号量的基本应用

  • 实现进程互斥
  • 实现进程间的前趋关系(有序)

实现多个进程互斥
设置一互斥信号量mutex,初值为1。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
互斥信号量注意点:

  1. 互斥信号量mutex初值为1;
  2. 每个进程中将临界区代码置于P(mutex)和V(mutex)原语之间
  3. 必须成对使用P和V原语(在同一进程中),不能次序错误、重复或遗漏:
    · 遗漏P原语则不能保证互斥访问
    · 遗漏V原语则不能在使用临界资源之后将其释放(给其他等待的进程);

实现有序

  • 前趋关系:
    并发执行的进程P1和P2中,分别有代码C1和C2,要求C1要在C2开始前完成;

  • 为每对前趋关系设置一个同步信号量S12,并赋初值为0。则只有V操作所在进程获得cpu时能运行
    在这里插入图片描述
    控制同步顺序的注意点

    • 信号量值为0的点是限制的关键所在;
    • 成对使用P和V原语(在有先后关系的两个进程中),不能次序错误、重复或遗漏,否则同步顺序出错。

如何利用互斥信号量解决上次课两个加法进程对共享变量操作的问题?在这里插入图片描述

民航售票系统问题

  • n个售票处。每个售票处通过终端访问系统的公用数据区
  • 假定公用数据区中分别用Ri表示某时间i次航班的现存票数。
  • Pi表示某售票处的处理进程,试用信号量实现进程间的互斥关系。

在这里插入图片描述

用信号量实现司机和售票员的同步。
在这里插入图片描述

4)AND型信号量

  • 出现原因:一些应用往往需要两个或多个共享资源,而不是前述的一个资源。进程同时要求的共享资源越多,发生死锁可能性越大。
  • 解决思想:
    一次性分配给进程所需资源,用完一起释放。Wait操作时对它所有需要的资源都要判断,有AND条件,故称“AND同步”、“同时wait”。

5)信号量集
引入原因:

  • 每次只能获得或释放一个单位的资源,低效;
  • 某些时候资源分配有下限的限制;
  • 修改:在大于可分配设置的下界值t前提下,每次可分配d个。

3. 管程

管程的组成

  1. 一组局部变量
  2. 对局部变量操作的一组过程
  3. 对局部变量进行初始化的语句。
    (联想面向对象中的类)
    在这里插入图片描述
    管程特点
  • 任何进程只能通过调用管程提供的过程入口才能进入管程访问共享数据;

    • 就如同使用临界资源,就要先通过其信号量的申请。
  • 任何时刻,仅允许一个进程在管程中执行某个内部过程。

管程如何实现同步?

  • 对共享变量互斥操作:
    • 管程的特点直接实现了该要求,进程一次一个进入管程调用内部过程操作共享变量。
    • 管程的互斥访问完全由编译程序在编译时自动添上,无须程序员关心,能保证正确。
  • 操作的同步控制:
    • 靠条件变量的操作管理实现。
      进入管程但不能获取资源操作的过程将阻塞,并在满足条件时被唤醒执行。
      在这里插入图片描述
      条件变量
      (主要作用就是进程同步的阻塞和唤醒控制)
  • 局部于管程的变量有两种:
    • 普通变量
    • 条件变量(用于控制进程阻塞和唤醒)
      • 类似信号量变量,但不取具体值;相当于每个阻塞队列的队列指针。
      • 对条件变量的操作需结合对普通变量的条件判断,从而控制进程状态。

管程的优点

  • 保证进程互斥地访问共享变量,并方便地阻塞和唤醒进程。管程可以以函数库的形式实现。相比之下,管程比信号量好控制。
  • 管程可增强模块的独立性:系统按资源管理的观点分解成若干模块,用数据表示抽象系统资源,使同步操作相对集中,从而增加了模块的相对独立性
  • 引入管程可提高代码的可读性,便于修改和维护,正确性易于保证:采用集中式同步机制。一个操作系统或并发程序由若干个这样的模块所构成,一个模块通常较短,模块之间关系清晰。

管程的缺点

  • 大多数常用的编程语言中没有实现管程,如果某种语言本身不支持管程,那么加入管程是很困难的。
  • 虽然大多数编程语言也没有实现信号量,但可将P、V操作作为一个独立的子例程或操作系统的管理程序调用加入。

4.进程通信

进程通信是指进程之间的信息交换。

一、低级通信——进程之间的互斥和同步
信号量机制是有效的同步工具,但作为通信工具缺点如下:

(1)效率低(通信量少)
(2)通信对用户不透明(程序员实现,操作系统只提供共享存储器供代码操作)

二、高级进程通信

用户直接利用操作系统提供的一组通信命令,高效地传送大量数据的通信方式。

  • 操作系统隐藏了进程通信的细节,对用户透明,减少了通信程序编制上的复杂性。

进程通信的类型

高级通信机制可归结为四大类
① 共享存储器系统(操作存储区方式)

  • 基于共享数据结构的通信方式(低级)
  • 基于共享存储区的通信方式(高级)

②消息传递系统(发–收方式)
③管道通信(中间文件方式)
④Client-Server system

消息传递通信的实现方法

1)直接通信方式
2)间接通信方式

消息传递系统的实现

单机和网络环境下的高级进程通信广泛采用“消息传递”方式,需要考虑的问题:

  • 通信链路的建立
  • 消息格式
  • 同步方式

消息缓冲队列通信机制

数据结构:
在这里插入图片描述

原语代码

  • 发送原语
    在这里插入图片描述
  • 接收原语
  • 在这里插入图片描述

线程:进程内的一条执行路径

多线程系统中,同一个进程中的多个线程

  • 共享进程资源
  • 可并发执行

线程的属性
多线程OS中,一个进程包括多个线程,每个线程都是利用CPU的基本单位。

  • 轻型实体:只需一点必不可少的、能保证独立运行的资源。(TCB)
  • 独立调度和分派的基本单位:调度切换迅速且开销小。
  • 可并发执行
  • 共享进程资源:同进程中的线程可共享相同的进程地址空间、已打开文件、信号量机构等。

线程的信息

状态参数

  • 标识符、运行状态、优先级、寄存器状态、堆栈、专有存储器、信号屏蔽等。
  • 运行状态
    执行、就绪、阻塞

线程的创建和终止

在多线程OS中,应用程序启动时,通常只有一个线程(初始化线程)在执行,它根据需要再创建若干线程。

  • 创建新线程
    利用线程创建函数(或系统调用),提供相应参数。线程创建函数执行完后,返回一个线程标识符供以后使用。
  • 线程被终止:
    不立即释放资源,只有当进程中的其它线程执行分离函数后,资源才分离出来能被其它线程利用。
    被终止而未释放资源的线程仍可被需要它的线程调用,使其重新恢复运行。

线程的管理

同步和通信机制
1)互斥锁

- 比较简单的,控制线程互斥访问资源;
- 适用于高频度使用的关键共享数据和程序段;
- unlock和lock两个锁操作原语;

2)条件变量

- 与互斥锁一起使用
- 锁保证互斥进入临界区,但利用条件变量使线程阻塞
- 注意不满足条件时,wait条件变量:
	-释放互斥锁
	-进程阻塞在条件变量指向队列中
	-被唤醒后要重新再设互斥锁

3)信号量

- 私用信号量(private samephore)
	- 用于同进程的线程间同步,数据结构存放在应用程序的地址空	间。属于特定进程,OS感知不到其存在。
- 公用信号量(public samephore)
	- 用于不同进程间或不同进程中线程的同步,数据结构由OS管理,存放在受保护的系统存储区。

线程的实现方式

1.内核线程KST(kernel-level thread)

  • 依赖于内核,利用系统调用由OS内核在内核空间完成创建、撤消、切换等线程工作。
    • 时间片分配给线程,所以多线程的进程获得更多CPU时间。

2.用户线程ULT(user-level thread)

无须利用系统调用,不依赖于OS核心。进程利用线程库函数创建、同步、调度和管理控制用户线程。
- 调度由应用软件内部进行,通常采用非抢先式和更简单的规则,也无需用户态/核心态切换,速度比kst快。

3.组合方式
内核支持多KST线程的管理,同时也允许用户应用程序级的线程管理。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值