操作系统原理一:进程管理 (5)

不用时有可能发生死锁

Swait(s1,s2,…,sn){ while(1){ if (s1>=1& …&sn >=1){ for(i=1;i<=n;i++) si--; break; } else{ //将进程放入与找到的第一个si<1的si相关的阻塞队列中 //并将该进程的程序计数设置为swait操作的开始 } } } Ssignal(s1,s2,…,sn){ while(1){ for (i=1;i<=n;i++){ si++; //将与si关联的队列中等待的所有进程都移动到就绪队列中 } } } 信号量集

为提高效率而对AND信号量的扩充

允许一次申请多种资源多个

ti为分配下限值,Si>=ti则不分配,di为该进程需求值

Swait(S1, t1, d1, …, Sn, tn, dn){ while(1){ if(Si>=ti& … &Sn>=tn) for (i=1;i<=n;i++) Si=Si-di; else{ //将进程放在Si<ti的第一个Si的阻塞队列中 //并将该进程的程序计数设置为swait操作的开始 } } } Ssignal(S1, d1, …, Sn, dn){ while(1){ for (i=1;i<=n;i++) { Si =Si+di; //将与si关联的队列中等待的所有进程都移动到就绪队列中 } } }

Swait(S,d,d):允许每次申请d个资源,少于d不分配

Swait(S,1,1):S>1记录型信号量,S=1互斥形信号量

Swait(S,1,0):可控开关,S>=1时允许同时进入,S<1时不允许

经典进程同步问题 生产者-消费者*

定义数据结构

int n; typedef item = xxx; //产品类型 item buffer [n]; //缓冲池 int in = 0,out = 0; int counter = 0; //产品数

缓冲池满时,生产者等待;为空时,消费者等待

记录型信号量

semaphore mutex=1,empty=n,full=0 item buffer[n]; //缓冲池 int in = 0,out = 0; int main() { cobegin: producer(); consumer(); coend } producer(){ while(1){ … produce an item in nextp; … wait(empty); wait(mutex); buffer[in]=nextp; in=(in+1)%n; signal(mutex); signal(full); } } consumer(){ while(1) { wait(full); wait(mutex); nextc=buffer[out]; out=(out+1)%n; signal(mutex); signal(empty); consumer the item in nextc; } }

P操作的顺序至关重要,顺序不当可能导致死锁(有缓冲池使用权,无缓冲)
V操作的顺序无关紧要
当缓冲区只有一个时,mutex可省略

AND信号量

semaphore mutex=1,empty=n,full=0; item buffer[n]; int in=0,out=0; main(){ cobegin producer(); consumer(); coend } producer() { while(1) { ... produce......; ... Swait(empty,mutex); buffer[int]=nextp; in = (in+1)mod n; Ssignal(mutex,full); } } consumer(){ while(1){ Swait(full,mutex); nextc=buffer[out]; out=(out+1)%n; Ssignal(mutex,empty); consumer......; } } 哲学家进餐

操作系统原理一:进程管理

5个哲学家围坐,用5只筷子吃面,筷子交替摆放

记录型信号量

设5个信号量表示5只筷子

AND信号量

同上

读-写*

读进程可共享对象,写进程不可

设整形变量readcount读者数wmutex读写互斥,rmutex互斥访问

记录型信号量:

semaphore rmutex=1,wmutex=1; int readcount=0; int main(){ cobegin: reader(); writer(); coend; } reader(){ while(1){ wait(rmutex); if(readcount==0) wait(wmutex);//无人读才能写 readcount++; signal(rmutex); ... read...... ... wait(rmutex); readcount--; if(readcount==0) signal(wmutex); signal(rmutex); } } writer(){ while(1){ wait(wmutex); ... write...... ... signal(wmutex); } }

写优先

semaphore rmutex=1,wmutex=1,s=1; int readcount=0; int main(){ cobegin: reader(); writer(); coend; } reader(){ while(1){ wait(s);//! wait(rmutex); if(readcount==0) wait(wmutex);//无人读 readcount++; signal(rmutex); signal(s);//! ... read...... ... wait(rmutex); readcount--; if(readcount==0) signal(wmutex); signal(rmutex); } } writer(){ while(1){ wait(s);//! wait(wmutex); ... write...... ... signal(wmutex); signal(s);//! } }

信号量集

#define RN 20//最大读者数 semaphore L=RN,mx=1; int main(){ cobegin: reader(); writer(); coend; } reader(){ while(1){ swait(L,1,1); swait(mx,1,0); ... read...... ... wait(rmutex); ssignal(L,1); } } writer(){ while(1){ swait(mx,1,1); swait(L,RN,0); ... write...... ... ssignal(mx,1); } } 管程

将同步操作的机制和临界资源结合到一起,避免了要使用临界资源的进程自备同步操作

管程:一个数据结构能为并发进程所执行的一组操作
包括:1. 局部对于管程的共享变量,2. 对该数据结构操作的一组过程,3. 对局部管程数据设初值

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zypfsj.html