操作系统PV大题汇总(408)

PV大题汇总文件下载

我用夸克网盘分享了「000000我的笔记」,点击链接即可保存。打开「夸克APP」,无需下载在线播放视频,畅享原画5倍速,支持电视投屏。
链接:https://pan.quark.cn/s/9589253580d6

笔记下载

链接:https://pan.baidu.com/s/1bFz8IX6EkFMWTfY9ozvVpg?pwd=deng
提取码:deng

b站视频:408-计算机网络-笔记分享_哔哩哔哩_bilibili
包含了408四门科目(数据结构、操作系统、计算机组成原理、计算机网络)
如果链接失效了,看看b站,或者私信我

408相关资料(真题 模拟卷等)

链接: https://pan.baidu.com/s/1Qga8aMgcrVfCmrry68vqog?pwd=974t
提取码: 974t

PV口诀

 互斥变量恒为1
 申请成功就释放
 PV操作总成对
 同步首先是申请
 生产消费要分开
 拿走放入俩变量

读者写者

有一个文件:

1、允许同时有多个进程进行读操作, 2、只允许一个进程同时进行写操作, 3、不能够在读操作的同时进行写操作

请设计读进程和写进程,以满足上述条件。

semophore mutex=1;                      //  用于互斥操作count和写锁
semophore writeMutex = 1;   	  // 写锁
int count=0;                                          //  统计读者,当为0时,申请写锁或者释放写锁
semophore x=1                           	    //  增加一个饥饿锁,防止writer饥饿,

void reader() {
    P(x);   // 申请 饥饿锁
        
    // 操作count 和 写锁
    P(mutex);
    if(count==0){               // 如果为0就申请
        P(writeMutex);
    }
    count++;    
    V(mutex);
    
    V(x);   // 释放 饥饿锁
    
    read();   // 进行读操作
    
    // 操作count 和 写锁
    P(mutex);
    count--;
    if(count==0){               // 如果为0就释放
        V(writeMutex);
    }
    V(mutex);
}

void writer(){
    P(x);       //  饥饿锁
    P(writeMutex);
    write();
    V(writeMutex);
    V(x);       //  饥饿锁
}

2009年大题

45.(7分)三个进程P1、P2、P3互斥使用一个包含N(N>0)个单元的缓冲区。

P1每次用produce()生成一个正整数并用put()送入缓冲区某一空单元中;

P2每次用getodd()从该缓冲区中取出一个奇数并用countodd(统计奇数个数

P3每次用geteven()从该缓冲区中取出一个偶数,并用counteven(统计偶数个数

请用信号量机制实现这三个进程的同步与互斥活动,并说明所定义信号量的含义(要求用伪代码描述)。

分析:1个缓冲区,2个消费者,1个生产者
semophore mutex=1;   
semophore empty=n;
semophore OddCount=0;
semophore EvenCount=0;

void P1(){
	while(1){
        int num = produce();  //  生成一个正整数
        P(empty);// 看看满了没有
        P(mutex); // 申请访问
        put();   // 放入缓冲区
        // 判断奇偶
        if(num %2 == 0){
            V(EvenCount);
        }else{
            V(OddCount);
        }
        V(mutex)// 释放
	}
}

void P2(){
    while(1){
        P(OddCount);    // 奇数-1
        P(mutex);    
        
        getodd();   // 获取奇数
        countodd();
        
        V(empty);    // 缓冲区空间+1
        V(mutex);
    }
}

void P3(){
    while(1){
        P(EvenCount);    // 偶数-1
        P(mutex);    
        
        geteven();   // 获取偶数
        counteven();
        
        V(empty);    // 缓冲区空间+1
        V(mutex);
    }
}



2011年大题

8分)某银行提供1个服务窗口10个供顾客等待的座位

顾客到达银行时,若有空座位,则到取号机上领取一个号,等待叫号。

取号机每次仅允许一位顾客使用。当营业员空闲时,

通过叫号选取一位顾客,并为其服务。顾客和营业员的活动过程描述如下:

cobegin(){
	process 顾客i()
	{
		从取号机获取一个号码;
		等待叫号;
		获取服务;
	}
	process营业员()
	{
        while(TRUE)
        {
            叫号;
            为客户服务;
        }
	}
}coend

请添加必要的信号量和P、V(或wait()、signal())操作,实现上述过程中的互斥与同步。
要求写出完整的过程,说明信号量的含义并赋初值。

分析:

营业员:消费者(1个

顾客:产品——产品位置:10——取号机(互斥使用)

semophore mutex=1;  // 互斥使用取号机
semophore cosumer=0;   // 顾客数量
semophore empty=10;     // 空位数量

semophore server=0; // 确保客户完成(实现同步

cobegin(){
	process 顾客i()
	{
         // P(empty)    空位-1
        // P(mutex)     互斥使用取号机
		从取号机获取一个号码;
         // V(mutex)    取完立即释放资源
        // V(cosumer)   顾客数量+1
       
		等待叫号; // V(server)  让快点来服务——同步关系 ✪ ✪ ✪
		获取服务;  
	}
    
	process营业员()
	{
        while(TRUE)
        {
            叫号;  // P(cosumer)   顾客 -1
            //  V(empty)   空位+1
            // P(server)  进行服务——同步关系 ✪ ✪ ✪
            为客户服务;  


        }
	}
}coend

2013年大题

博物馆最多可容纳500人同时参观,有一个出入口,该出入口一次仅允许一个人通过。

参观者的活动描述如下:

cobegin(){
	参观者进程i()
	{
         进门;
         ...
         参观;
         ...
         出门;
	}
}coend

请添加必要的信号量和P、V(或wait()、signal())操作,实现上述过程中的互斥与同步。
要求写出完整的过程,说明信号量的含义并赋初值。

分析: visitor(){} 参观者进程,出入口(互斥),博物馆(500人

参观者 – 入口(互斥) – 人数+1 – 出口(互斥) – 人数-1

semophore  mutex=1;  // 互斥访问【出入口】
semophore  empty=500;  // 空闲500人
参观者进程i()
	{
    	// P(empty)空闲-1
		// P(mutex)
         进门;
        // V(mutex)
         ...
         参观;
         ...
         // V(mutex) 
         出门;
        // V(mutex)
        // P(empty)空闲+1
	}

2014年大题

系统中有多个生产者进程和多个消费者进程,共享一个能存放1000件产品的环形缓冲区(初始为空)。

当缓冲区未满时,生产者进程可以放入其生产的一件产品,否则等待;

当缓冲区未空时,消费者进程可以从缓冲区取走一件产品,否则等待。

要求一个消费者进程从缓冲区连续取出10件产品后,其他消费者进程才可以取产品。

请添加必要的信号量和P、V(或wait()、signal())操作,实现上述过程中的互斥与同步。
要求写出完整的过程,说明信号量的含义并赋初值。

semophore empty=1000; // 可以放1000个
semophore all =0;  // 生成了多少
semophore mutex=1; // 互斥访问【环形队列缓冲区】
semophore x=1;   // 互斥拿取【10个产品

void ProducerN(){
    生产一个产品
    P(empty)     // 判断有没有空位
    P(mutex)   
    把产品放入缓冲区
    V(mutex)
     V(all)        // 产品+1
}

void CostumerN(){
    P(x) // 互斥拿取
	for( int i=0; i<10; i++){
        P(all)        // 判断有没有产品
        P(mutex)   
        获取一个产品
        V(mutex)
        V(empty)     // 空闲 +1 
        
    }
     V(x) // 开锁
}

2015年大题

45.(9分)有A、B两人通过信箱进行辩论,每个人都从自己的信箱中取得对方的问题。

将答案和向对方提出的新问题组成一个邮件放入对方的邮箱中。

假设A的信箱最多放M个邮件,B的信箱最多放N个邮件。

初始时A的信箱中有x个邮件(0,B箱中有y个(0每取出一个邮件,邮件数减1。

A和B两人的操作过程描述如下:

A{																																B{
	while(TRUE){																										while(TRUE){
        从A的信箱中取出一个邮件;																				 从B的信箱中取出一个邮件;
        回答问题并提出一个新问题;																				回答问题并提出一个新问题;
        将新邮件放入B的信箱;																							将新邮件放入A的信箱;

当信箱不为空时,辩论者才能从信箱中取邮件,否则需要等待。

当信箱不满时,辩论者才能将新邮件放入信箱,否则需要等待。

请添加必要的信号量和P、V(或wait()、signal())操作,实现上述过程中的互斥与同步。
要求写出完整的过程,说明信号量的含义并赋初值。

分析:2个邮箱(互斥)并且限制大小、 2个都会被相互访问,

semophore Amutex=1;   // 互斥访问A邮箱
semophore Bmutex=1;   // 互斥访问B邮箱
semophore Aempty=M;  // 可以放M个    这里出问题了 应该是M-x
semophore Bempty=N;  // 可以放个N     这里出问题了   N-y
semophore Anum=0;  //  A 存在的邮件
semophore Bnum=0;  //  B 存在的邮件

A{																															
	while(TRUE){			
    	// P(Anum)        看看邮箱中是否有
        // P(Amutex)     互斥访问
        从A的信箱中取出一个邮件;		
        // V(Amutex)
        // V(Aempty)     空位+1
            
        回答问题并提出一个新问题;	
            
        // P(Bempty)     看看邮箱里面是否满了
        // P(Bmutex)     互斥访问
        将新邮件放入B的信箱;												
        // V(Bmutex)            
        // V(Bnum)        邮件+1
    }

B{																															
	while(TRUE){			
    	// P(Bnum)        看看邮箱中是否有
        // P(Bmutex)     互斥访问
        从B的信箱中取出一个邮件;		
        // V(Bmutex)
        // V(Bempty)     空位+1
            
        回答问题并提出一个新问题;	
            
        // P(Aempty)     看看邮箱里面是否满了
        // P(Amutex)     互斥访问
        将新邮件放入A的信箱;												
        // V(Amutex)            
        // V(Anum)        邮件+1
    }

答案

semaphore Full_A =x;					//Full_A表示A的信箱中的邮件数量
semaphore Empty_A = M-x;		//Empty_A表示A的信箱中还可存放的邮件数量
semaphore Full_B = y;					//Ful1_B表示B的信箱中的邮件数量
semaphore Empty_B = N-y;		//Empty_B表示B的信箱中还可存放的邮件数量
semaphore mutex_A = 1;				//mutex_A用于A的信箱互斥
semaphore mutex_B = 1;				//mutex_B用于B的信箱互斥
A{																														B{
while(TRUE){																									while(TRUE){
P(Full_A);																													P(Full_B);
P(mutex_A);																											 P(mutex_B);
从A的信箱中取出一个邮件;																				 从B的信箱中取出一个邮件;
V(mutex_A);																											  V(mutex_B);
V(Empty_A);																												V(Empty_B);
回答问题并提出一个新问题;																				回答问题并提出一个新问题;
P(Empty_B);																												P(Empty_A);
P(mutex_B);																												P(mutex_A);
将新邮件放入B的信箱;																							将新邮件放入A的信箱;
V(mutex_B);																												V(mutex_A);
V(Full_B);																													 V(Full_A);

2017年大题

程中有3个并发执行的线程thread1、thread2和thread3,其伪代码如下所示。

//复数的结构类型定义
typedef struct{
    float a;
    float b;
}cnum

cnum  x, y ,z;    //全局变量

//计算两个复数之和
cnum add(cnum p, cnum q){
    cnum s;
    s.a=p.a+q.a;
    s.b=p.b+q.b;
    return s;       
}


thread1(){
    cnum w:
    w=add(x, y);
    ...
}

thread2(){
    cnum w;
    w=add(y,z)...
}


thread3(){
    cnum w;
    w.a = 1;
    w.b = 1;
    z=add(z,w);
    y=add(y,w)...
}

请添加必要的信号量和P、V(或wait()、signal())操作,要求确保线程互斥访问临界资源,
并且最大限度地并发执行。

分析:如果是一读一写或两个都是写,那么这就 是互斥关系。每一个互斥关系都需要一个信号量进行调节。

//复数的结构类型定义
typedef struct{
    float a;
    float b;
}cnum

cnum  x,y,z;    //全局变量


semophore YmutexR = 1;	  // 互斥读y   (读锁
semophore YmutexW = 1;  // 互斥写y   (写锁
semophore Zmutex = 1;	  // 互斥访问z


//计算两个复数之和
cnum add(cnum p, cnum q){
    cnum s;
    s.a=p.a+q.a;
    s.b=p.b+q.b;
    return s;       
}

thread1(){
    cnum w:

    P(Ymutex)      
    w=add(x, y);
    V(Ymutex)
}

thread2(){
    cnum w;
    P(YmutexR)       // 读锁
    P(Zmutex)
    w=add(y,z)V(ZmutexR)
    V(Ymutex)

}

thread3(){
    cnum w;
    w.a = 1;
    w.b = 1;
    P(Zmutex)
    z=add(z,w)// 修改z
    V(Zmutex)

    P(YmutexR)      // 读锁
    P(YmutexW)      // 写锁
    y=add(y,w)// 修改y
    V(YmutexW)
    V(YmutexR)    
}

2019年大题(哲学家)

43.(8分)有n(n≥3)位哲学家围坐在一张圆桌边,每位哲学家交替地就餐和思考。

在圆桌中心有m(m≥1)个碗,每两位哲学家之间有一根筷子。

每位哲学家必须取到一个碗和两侧的筷子后,才能就餐,进餐完毕,将碗和筷子放回原位,并继续思考。

为使尽可能多的哲学家同时就餐,且防止出现死锁现象,请使用信号量的P、V操作[wait()、signal()操作]描述上
述过程中的互斥与同步,并说明所用信号量及初值的含义。

// 信号量
semaphore bowl;					    	//用于协调哲学家对碗的使用
semaphore chopsticks[n];	  //用于协调哲学家对筷子的使用

for(int i=0; i<n; i++)
    chopsticks[i]=1;		//设置两个哲学家之间筷子的数量
bowl=min(n-1,m);        //bowl ≤n-1,确保不死锁

CoBegin
while(TRUE){    //哲学家i的程序
    思考;
    P(bowl);        //取碗
    P(chopsticks[i])//取左边筷子
    P(chopsticks[(i+1)%n]);    //取右边筷子
    就餐;
    V(chopsticks[i]);
    V(chopsticks[(i+1)%n]);
    V(bowl);
}
CoEnd

2020年大题

45、(7分)现有5个操作A、B、C、D和E,操作C必须在A和B完成后执行,操作E必须
在C和D完成后执行,请使用信号量的waitO、signalO操作(P、V操作)描述上述操作
之间的同步关系,并说明所用信号量及其初值。

semaphore A=0;    // 控制A 和C 的执行顺序
semaphore B=0;    // 控制B 和C 的执行顺序

semaphore C=0;    // 控制C 和E 的执行顺序
semaphore D=0;    // 控制D 和E 的执行顺序

A(){
    完成A操作;
    V(A);     //实现A、C之间的同步关系
}

B(){
    完成B操作;
    V(B);     //实现B、C之间的同步关系
}


C(){
    //  C 必须在A、B 都完成后才能完成
    P(A);
    P(B);
    完成C操作;
    V(C);     
}

D(){
    完成D操作;
    V(D);     //实现D、E之间的同步关系
}



E(){
    //  E 必须在C、D 都完成后才能完成
    P(C);
    P(D);
    完成E操作;
}

2023年大题

要求学生使用swap指令和布尔型变量lock,实现临界区互斥。lock为线程间共享的变量。

lock的值为TRUE时线程不能进入临界区,为FALSE时,线程能进入临界区。

某同学编写的实现临界区互斥的伪代码如题

// 某同学编写的伪代码
Bool lock=FALSE;     	//共享变量
...
 // 进入区
Bool key=TRUE    
If (key== TRUE)
	Swap(key,  lock);		//交换key和lock的值
...
//   临界区
...
Lock=TRUE;    // 退出区
...
// newSwap0的代码
Void newSwap(bool*a, bool*b){
    bool temp=*a
	*a=*b;
	*b=temp
}

(1)题45(a)图的伪代码中哪些语句存在错误?将其改为正确的语句(不增加语句条数)。
(2)题45(b)图给出了两个变量值的函数newSwap()的代码,是否可以用函数调用语句“newSwap(&key,&lock)”代替指令“swapkey,lock”以实现临界区的互斥?为什么?

while (key== TRUE)
	Swap(key,  lock);		//交换key和lock的值

Lock=FALSE;    // 退出区

第一问 :

  • A线程,如果是第一个,那必然成功,在while循环中交换后,key=False,就会跳出循环,进入临界区
  • 后面的线程B,在跑来交换,因为lock=True了,那么2个变量都是T,导致他会一直循环,不停的交换
  • 等到A访问完临界区那里面的代码,就把Lock变为False,让后者可以跳出循环,进入临界区

第二问

  • B(lock)=F时
  • 有两个线程同时运行到a=b,他们的a(key)就是F,函数运行完,他们都会跳出while循环!
  • 他们就会一起进入临界区!

你可能感兴趣的:(其他,操作系统,PV大题,408)