进程同步与互斥——相关问题汇总(源码+伪代码)

本文详细介绍了多个经典的进程同步与互斥问题,包括生产者消费者问题、哲学家就餐问题、读者/写者问题、理发师问题等,并提供了相应的伪代码实现。通过信号量机制,实现了进程间的互斥访问和同步操作,确保了系统资源的有效利用和避免了死锁。同时,还分析了各种场景下信号量的含义和初值设定,帮助理解并发控制策略。

说明:问题摘录于王道考研书籍,作为学习记录使用,其中一些经典的进程同步互斥问题,写了一下源代码测试跑了一下。

详见:

进程同步与互斥——信号量(实现锁、条件变量)

进程同步与互斥——哲学家就餐问题源码实现(dining philosopher’s problem)

进程同步与互斥——读者/写者问题源码实现(reader-writer lock)

进程同步与互斥——生产者/消费者(有界缓冲区)问题源码实现

进程同步与互斥——吸烟者问题源码实现(cigarette smoker’s problem)

进程同步与互斥——理发师问题源码实现(sleeping barber problem)

进程同步与互斥——相关问题汇总(源码+伪代码)

下面index索引的题目实现均用伪代码所实现

index

生产者——消费者问题

semaphore empty = n;     //空闲缓冲区
semaphore full = 0;      //缓冲区初始化为空
semaphore mutex = 1;     //临界区互斥信号量
producer() {
   
   
	while(1) {
   
   
		produce an item;
		p(empty);
		p(mutex);
		add an item to buffer;
		v(mutex);
		v(full);
	}
}
consumer() {
   
   
	while(1) {
   
   
		p(full);
		p(mutex);
		remover an item from buffer;
		v(mutex);
		v(empty);
		consume the item;
	}
}

index1

问题描述:

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

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

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

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

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

问题分析:

semaphore empty = N;        //缓冲区的大小N
//semaphore full = 0;       //no use
semaphore odd = 0;          //取奇数进程的consumer和producer之间的同步信号量
semaphore even = 0;         //取偶数进程的consumer和producer之间的同步信号量
semaphore mutex = 1;        

process producer()
{
   
   
	int number = produce();
    P(empty);
    P(mutex);
    //put(number)
    V(mutex);
    if(number % 2 == 0)
    {
   
   
        V(even);
    }
    else
    {
   
   
		V(odd);
    }	
}

process consumer1()
{
   
   
	P(odd);
    P(mutex);
    //getodd()
    V(mutex);
    V(empty);
    //countodd();
}

process consumer2()
{
   
   
	P(even);
    P(mutex);
    //geteven()
    V(mutex);
    V(empty);
    //counteven();    
}

index2

问题描述:

某博物馆最多可容纳500人同时参观,有一个出入口,该出入口一次仅允许一个人通过。参观者的活动描述如下:

cobegin
参观者进程i:
{
   
   
	//进门
	//参观
	//出门
}
coend

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

问题分析:

//错误的解法,该题中提到了只有一个出入口,就是只有一个门,可以是出,也可以入,每次只能一个人过
semaphore out = 1;
semaphore in = 1;
semaphore buffer = 500;

cobegin
	参观者进程i:
	{
   
   
        P(buffer);
        P(in);
        //进门
        V(in);
        //参观
        P(out);
        //出门
        V(out);
        V(buffer);
    }
coend

出入口一次仅允许一个人通过,设置互斥信号量mutex,初值为1。博物馆同时最多可容纳500人,因此设置信号量empty,初值为500。

semaphore mutex = 1;
semaphore empty = 500;

cobegin
	参观者进程i:
	{
   
   
        P(empty);
        P(mutex);
        //进门
        V(mutex);
        //参观
        P(mutex);
        //出门
        V(mutex);
        V(empty);
    }
coend

index3

问题描述:

某工厂有两个生产车间和一个装配车间,两个生产车间分别生产A、B两种零件,装配车间的任务是把A、B两种零件组装成产品。两个生产车间每生产一个零件后都要分别把它们送到装配车间的货架F1、F2上,F1存放零件A,F2存放零件B,F1和F2的容量均为可以存放10个零件。装配工人每次从货架上取一个A零件和一个B零件然后组装成产品。请用多线程并发进行正确的管理。

问题分析:

这个问题是本质还是生产者,消费者模型,其中生产者A车间和消费者车间共享缓冲区F1,生产者B车间和消费者车间共享缓冲区F2。因为,对于每个车间而言,其访问缓冲区都是并发进行的,可能有多个车间工人同时对缓冲区的状态进行改变,因此这个模型是多生产者/多消费者模型,在进程间代码中对于缓冲区状态改变的部分都需要进行互斥操作,以防止同时改变缓冲区状态而出错。

semaphore empty1 = 10;    //F1的空闲容量
semaphore full1 = 0;      //F1中A零件数目
semaphore mutex1 = 1;     //用于进程间互斥访问缓冲区
semaphore empty2 = 10;
semaphore full2 = 0;
semaphore mutex2 = 1;

process1()
{
   
   
	while(1)
	{
   
   
		//生产零件A
		P(empty1);    //判断货架F1是否为空
		P(mutex1);    //互斥访问货架F1
		//将产品A存放在货架F1上  
		V(mutex1);    //释放货架F1
		V(full1);	  //货架F1上的零件A的个数加1
	}
}

process2()
{
   
   
	while(1)
	{
   
   
		//生产零件B
		P(empty2);    //判断货架F2是否为空
		P(mutex2);    //互斥访问货架F2
		//将产品B存放在货架F2上  
		V(mutex2);    //释放货架F2
		V(full2);	  //货架F2上的零件B的个数加1
	}
}

process3()
{
   
   
	while(1)
	{
   
   
		P(full1);     //F1货架上是否有零件
		P(mutex1);    //互斥访问货架F1
		//在F1货架上取A零件
		V(mutex1);    //释放货架F1 
		V(empty1);    //F1货架的空位数加1
		P(full2);
		P(mutex2);
		//在F2货架上取B零件
		V(mutex2);
		V(empty2);
		//将A零件和B零件组装成产品
	}
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值