文章目录
2.4 进程同步
采用躲到程序设计技术的操作系统,允许多个进程同时驻留内存并发执行。进程同步的主要任务:使并发执行的诸进程之间能有效地共享资源和相互合作,从而使程序的执行具有可再现性
1.两种制约方式
- 间接相互制约——————共享系统资源
- 直接相互制约——————进程间合作
2.临界资源
- 某些资源必须互斥使用,称为临界资源
- 访问临界资源的那段代码成为临界区
- 当临界区中的进程使用完毕时,负责唤醒阻塞队列中的一个进程,让其进入临界区
- 为了保证进程间互斥执行自己的临界区,就要保证“临界区使用标志”是可被系统中所有进程共享的“全局变量”
3.临界区使用原则(互斥条件)
- 空闲让进:如果临界区空闲,有进程申请就立即让其进入
- 忙则等待:每次仅允许一个进程处于临界区,保证对临界资源的互斥访问
- 有限等待:临界区内的进程只有逗留有限时间,不能令其他进程在临界区外死等
- 让权等待:进程不能进入临界区,应立即释放处理机,以免进入忙等
4.竞争资源可能引起的问题
- 忙等:进程需要循环检测
- 死锁
- 饥饿:当一个进程退出临界区,有多个进程想进入,则只能进一个
5.互斥与同步的解决策略
-
软件方法:进程通过执行相应的程序指令,实现与其他进程的互斥与同步(大幅度增加系统开销)————Dekker算法和Peterson算法
软件方法通常能实现两个进程的互斥,很难控制多个进程的互斥
-
硬件方法:通过屏蔽中断(单CPU)或采用专门的机器指令控制互斥与同步(太强的约束会导致饥饿和死锁)。
- 进程运行中如果屏蔽了中断则不会出现进程切换就确保了互斥执行。
- 但在多处理机中用屏蔽中孤单不能确保互斥与同步
-
操作系统提供的方法:信号量已经成为控制进程同步与互斥的通用方法 (解决了软件和硬件方法中忙等的问题)
-
整形信号量:除初始化外,仅能通过两个标准的原子操作wait(S)和signal(S)来访问。也称为P,V操作
wait用于申请资源,可能会阻塞自己
signal用于释放资源,有责任唤醒一个阻塞进程 -
记录型信号量:一个域为整形,一个域为队列,队列的元素为等待该信号量的阻塞进程。
记录型信号量的wait(S)操作
记录型信号量的signal(S)操作
-
AND型信号量:将所有资源一次性全都分配给进程,使用完后再一次性释放。只要有一个资源没有准备好就不分配给他
-
信号量的类型:
-
互斥信号量:用于申请或释放资源的使用权,常初始化为1。
-
资源信号量:用于申请或归还资源,可以初始化为大于1的正整数,表示系统中某类资源的可用个数。
-
-
利用信号量实现进程互斥
- 为使多个进程能互斥地访问某临界资源,只须为该资源设置一互斥信号量mutex,并设其初始值为1
- 然后将各进程访问该资源的临界区CS置于wait(mutex)和signal(mutex) 操作之间即可。
-
信息量集——Swait和Ssignal
-
6.信号量的应用
-
利用信号量实现进程互斥:
——为该资源设置一互斥信号量mutex,并设其初始值为1,然后将各进程访问该资源的临界区CS置于wait(mutex)和signal(mutex)操作之间即可。 -
利用信号量实现前趋关系
7.经典进程的同步问题
生产者消费者问题:
生产者和消费者进程共享一个大小固定的缓冲区。
一个或多个生产者生产数据,并将生产的数据存入缓冲区。
一个消费者从缓冲区中取数据。
互斥信号量mutex:实现诸进程对缓冲池的互斥使用;
资源信号量empty:表示缓冲池中空缓冲区的数量;
资源信号量full:表示满缓冲区的数量;
producer:
wait(empty);
wait(mutex);
buffer(in):=nextp;
in:=(in+1)mod n;
signal(mutex);
signal(full);
consumer:
wait(full);
wait(mutex);
nextc :=buffer(out);
out:= (out+1)mod n;
signal(mutex);
signal(empty);
注意:
- 进程应该先申请资源信号量,在申请互斥信号量
- wait和signal必须配对
- 同一个资源信号量的wait与signal可以不在同一个进程中
- wait一定先于signal语句
读者/写者问题
多个进程访问一个共享数据区
存在若干读进程只能读数据,若干写进程只能写数据
允许多个读进程同时读
不允许多个写进程同时写
如果有写进程正在写不允许读
如下代码中申请了两个信号量:
- readcount:指明正在读数据的读进程数量
- wmutex:用于互斥读者和写者,只有当readcount==0时才提供给写进程,不然被第一个读进程占有
- rmutex:用于互斥读进程对readcount的修改
8.进程间通信
信号量机制作为同步工具是卓有成效的,但作为通工具,则不够理想。原因:1,效率低 2,对用户不透明
进程通信类型
-
共享存储器——共享数据结构:如生产者消费者中,就是理由有界缓冲区,但是非常低效,只适用于少量数据,该情况下由操作系统实现
-
管道:管道必须提供以下三方面的协调能力:
- 互斥:每个进程间互斥
- 同步:写完了等待读,没有可读就等待写
- 只有确认管道双方都存在,才能进行通信
-
消息传递
-
直接通信:直接利用OS提供的发送send和接收recieve命令
- send:即A先设置好发送区,计算正文长度申请并复制到缓冲区,然后找到B的PCB中的mq,将这个缓冲区插入到mq
- recieve:从缓冲区中接收
注意:缓冲区的读写应该互斥
-
间接通信
1)信箱:相当于一个中间方,分为私用,公用和共享。又有一对多,多对一,一对一,多对多这四种关系
2)缓冲队列
-
-
C/S——网络通信,套接字,RPC
9. 线程
- 进程是资源分配的基本单位
- 线程是调度的基本单位,所以线程自己不拥有系统资源,只需要一点必不可少的资源,但他可以访问隶属进程的资源。独立性必进程低。系统开销比进程小
- 通常一个进程都拥有若干个线程,至少有一个线程————》线程切换不影响进程,进程切换带动线程切换
- 进程可并发,且进程中的线程也可并发
线程间的同步和通信
互斥锁:两种状态——unlock || lock
线程实现方式
-
内核支持线程:即无论是用户进程中的线程,还是系统进程中的线程,他们的创建、撤消和切换等,也是依靠内核实现的。同样有线程控制块
缺点:用户进程的线程在用户态运行,而线程调度和管理是在内核实现的,需要从用户态转到内核态进行
-
用户级线程:通常是发生在一个应用进程的诸多线程之间,这时,也同样无须内核的支持。由于切换的规则远比进程调度和切换的规则简单,因而使线程的切换速度特别快。可见,这种线程是与内核无关的。
采用线程的优点
- 创建,终止,切换线程的时间比进程少
- 线程提高了不同的执行程序间通信的效率。同一个进程中的线程共享存储空间和文件,它们无需调用内核就可以互相通信。