问题:消息缓冲区为k个,有m个发送进程,n个接收进程,每个接收进程对发送来的消息都必须取一次。试用PV操作解决发送进程和接收进程之间的正确通信问题。
基本想法:接收进程内添加变量计数,记录当前进程当前的读取位置。
首先对原有问题进行简化,消息缓冲区无限大,有m个发送进程,n个接收进程,每个接收进程对发送来的消息都必须取一次。
由于消息缓冲区无限大,因此从发送进程来看,不需要考虑pop()方法,只需要考虑push()方法,考虑到变量的互斥操作,则send进程的代码如下:
send()
{
while(true)
{
P(mutex);
int tmp = rear;
rear=(rear+1); // 若考虑maxSize 则应为rear=(rear+1)%maxSize;
V(mutex);
Qlist[tmp]=item; //进行发送操作
}
}
而对于接收进程,为了获取应接收的消息的序号,为每个进程添加一个计数变量,记录当前应接收信息的序号。
Receive()
{
int front[i]; //front[i]记录编号为i的进程当前接收消息的序号
while(true)
{
P(mutex);
if(front[i] {
V(mutex);
receive();
front[i]++;
}
else
V(mutex);
}
}
这种情况下,运行m个发送进程,n个接收进程,读取次数不需要判断。
而在消息缓冲区个数k的情况下,为保证每个接收进程可以接收消息,添加变量 frontMin,用于记录当前全部接收进程中已接收消息的最小编号,初始值为0。另外,由于消息缓冲区空间有限,需要对当前的已用空间进行统计。
send()
{
while(true)
{
P(mutex);
int tmp = rear;
P(mutexCurrLen);
int tmpRear =(rear+1)%k;
P(mutexFrontMin );
while(tmpRear == frontMin)
/*忙等待*/;
V(mutexFrontMin );
rear=tmpRear;
V(mutexCurrLen);
V(mutex);
Qlist[tmp]=item;
}
}
Receive()
{
int front[i];
while(true)
{
P(mutex);
while(front[i]==rear)
/*忙等待*/;
V(mutex);
receive();
P(mutexFront); //针对数组front[]的信号量
P(mutexFrontMin );
front[i]++;
setFrontMin();
V(mutexFrontMin );
V(mutexFront);
}
}
阅读(1505) | 评论(0) | 转发(0) |