计算机操作系统教学知识点,计算机操作系统部分知识点总结2

信号量解决进程同步问题

1.前趋图

前趋图是一个有向无循环图,记为DAG(Directed Acyclic Graph),用于描述进程之间执行的前后关系。

图中的每个结点可用于描述一个程序段或进程,乃至一个语句;结点间的有向边‘→’则用于表示两个结点之间存在的偏序或前趋关系。

图示含义:A必须在B开始前结束

2.前趋图练习

例题:假设某个程序段包含如下 语句 ,画出它前趋图。

int a,b,c,d,e,f;

int t1,t2,t3,t4,t5;

s1:  t1=a+b;

s2:  t2=c+d;

s3:  t3=e/f;

s4:  t4=t1*t2;

s5:  t5=t4-t3;

3.程序的两种执行方式的特征对比

4.进程间状态的转换

5.进程同步的主要任务

对多个相关进程在执行次序上进行协调,以使并发执行的诸进程之间能有效地共享资源和相互合作,从而使程序的执行具有可再现性。

6.进程间的两种制约关系

①间接相互制约

源于资源共享,即对资源的竞争关系,进程需要互斥访问同一资源。

②直接相互制约

源于进程合作,即协作关系,某些进程为完成同一任务需要分工协作。

7.临界资源和临界区

临界资源(Critical Resource):只允许进程互斥访问的资源。例如,打印机,共享变量…

临界区(Critical section):进程中访问临界资源的代码段。

若能保证各进程互斥地进入自己的临界区,就可实现各进程对临界资源的互斥访问。

8.信号量机制类型

①整型信号量

定义S为一个用于表示资源数目的整型量,除初始化外,仅能通过两个标准的原子操作wait(S)和signal(S)来访问。这两个操作也被称为P、V操作。

wait(S) {

while (S<=0);  //do no-op,“忙等”

S--; }

signal(S) {  S++; }

存在问题: 未遵循“让权等待”的准则

②记录型信号量

在信号量机制中,除了需要一个用于代表资源数目的整型变量value外,还应增加一个进程链表指针L,用于链接上述的所有等待进程。

因采用了记录型数据结构而得名:

typedef struct {

int value;

struct process_control_block *list;

}semaphore;

wait (semaphore *S)  {

S->value--;

if (S->value <0) block(S->list); }

signal (semaphore *S)  {

S->value++;

if (S->value <=0) wakeup(S->list); }

③AND型信号量

基本思想:

将进程在整个运行过程中需要的所有资源,一次性全部地分配给进程,待进程使用完后再一起释放。只要尚有一个资源未能分配给进程,其他所有可能为之分配的资源,也不分配给它。亦即,对若干个临界资源的分配,采取了原子操作方式:要么全部分配给进程,要么一个也不分配。

AND型信号量wait原语为Swait, 定义如下:

Swait (S1, S2, …, Sn) {

if (Si >=1 && … && Sn >= 1) {

//进程所需各项资源都能满足时

for (i = 1; i <= n; ++i) Si--;

}

else {      //某些资源不够时的处理

把进程放入第一个小于1的信号量Sj的等待队列Sj.queue,并将程序计数器指向Swait的开始处;

}

}

AND型信号量集signal原语为Ssignal, 其定义如下:

Ssignal (S1, S2, …, Sn) {

for (i = 1; i <= n; ++i)

Si=Si++;    //释放占用的资源;

把等待Si的所有进程从等待队列移至就绪队列;

}

}

④信号量集

信号量集机制的适用范围更广,不仅能处理前述信号量机制能处理的问题,还能处理以下情况:

1)需要一次性分配多个同类资源时

2)当资源数量低于某一下限值时,就不予以分配

对AND型信号量加以扩充,即得到更为一般化的信号量集机制:

Swait (S1, t1, d1, …, Sn, tn, dn);

Ssignal (S1, d1, …, Sn, dn);

//ti:分配下限值,如果Si

//di:资源需求值,分配时Si-=di;   释放时Si+=di;

9.经典进程同步问题

1.生产者消费者问题

问题描述:

生产者-消费者问题是对相互合作的进程之间同步问题的一种抽象,例如,在输入和计算进程间,计算进程是消费者;而在计算和打印进程间,计算进程是生产者。

int in=0, out=0;

item buffer[n];

semaphore mutex=1, empty=n, full=0;

void producer() {

do {

produce an item in nextp;

wait (empty);

wait (mutex);

buffer(in):=nextp;

in:=(in+1) mod n;

signal(mutex);

signal (full);

} while(TRUE);

}

void consumer() {

do {

wait(full);

wait(mutex);

nextc:=buffer(out);

out:=(out+1) mod n;

signal(mutex);

signal(empty);

consume the item in nextc;

}while(TRUE)

}

void main() {

cobegin

producer(); consumer();

coend

}

2.哲学家进餐问题

问题描述:假设有五个哲学家,他们花费一生的时光思考和吃饭。这些哲学家公用一个圆桌,每个哲学家都有一把椅子。在桌中央有一碗米饭。每个哲学家面前有一只空盘子,每两人之间放一根筷子。当一个哲学家思考时,他与其他同事不交互;当哲学家感到饥饿,就会试图拿起与他最近的两支筷子(他与邻近左、右两人之间的筷子)。当一个饥饿的哲学家拿到两支筷子时才能进餐。当吃完后,他会放下两支筷子,并再次开始思考。

解法1

semaphore chopstick[5] = {1,1,1,1,1};

semaphore room =4;

int i;

void philosopher (int i);{

while ⑴ {

think( );

wait (room);

wait (chopstick[i]);

wait (chopstick [(i+l) %5]);

eat( );

signal (chopstick [(i+l) % 5]);

signal (chopstick[i]);

signal (room);

}

}

解法2

设chopstick[5]为5 个信号量,初值均为1

Philosopher(i)

while (1) {

思考;

Swait( chopstick[i], chopstick[(i+1) % 5] );

进食;

Ssignal( chopstick[i], chopstick[(i+1) % 5] );

}

解法3

semaphore chopstick[5] = {1,1,1,1,1};

int i;

void philosopher (int i);{

while ⑴ {

think( );

if (i mod 2 ==1) {//奇数号的哲学家必须首先拿左边的筷子

wait(chopstick[i]);

wait(chopstick [(i+l) %5]);

}

else {//偶数号的哲学家必须首先拿右边的筷子

wait (chopstick [(i+l)% 5]);

wait (chopstick[i]);

}

eat( );

signal(chopstick [(i+l) % 5]);

signal(chopstick[i]);

}

}

3.读者写者问题

问题描述:一组读者与一组写者循环访问共享的同一个数据对象。规定:多个读者可以同时读这个数据对象,但决不允许多个写者同时对它进行写操作,也不允许读者、写者同时访问它。如何对读者、写者编程?

读者 Readers:

begin

repeat

wait(rmutex);

if readcount=0 then wait(wmutex);

readcount:=readcount+1;

signal(rmutex);

执行读操作;

wait(rmutex);

readcount:=readcount-1;

if readcount=0 then singal(wmutex);

singal(rmutex);

until false;

end

写者 Writers:

begin

repeat

wait(wmutex);

执行写操作;

singal(wmutex);

until false;

end

10.独木桥问题

问题描述:一条小河上有一座独木桥,规定每次只允许一人过桥。如果把每个过桥者看作一个进程,为保证安全,请用信号量操作实现正确管理。

解:为临界资源独木桥设置信号量s,初值为1

begin

semaphore s=1;

cobegin

begin

wait(s);

过桥;

signal(s);

end

coend

end

独木桥问题拓展:

问题描述:若独木桥任何时刻最多允许2人同方向过桥,如何用信号量实现同步?

int count1=count2=0;

semaphore m0=m1=m2=1;

semaphore room=2;

方向1的过桥者:

begin

wait(m1);

if(count1==0) wait(m0);

count1++;

signal(m1);

wait(room);

过桥;

signal(room);

wait(m1);

count1--;

if(count1==0) signal(m0);

signal(m1);

end

方向2的过桥者:

begin

wait(m2);

if(count2==0) wait(m0);

count2++;

signal(m2);

wait(room);

过桥;

signal(room);

wait(m2);

count2--;

if(count2==0) signal(m0);

signal(m2);

end

进程同步类型的问题很多,具体请参照网上的其他问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值