PV操作的两个例子

生产者消费者

2.6 设有三个进程 A、B、C,其中 A 与 B 构成一对生产者与消费者(A 为生产者,B 为消费者),共享一个由 n 个缓冲块组成的缓冲池;B 与 C 也构成一对生产者与消费者(此时 B 为生产者,C 为消费者),共享另一个由 m 个缓冲块组成的缓冲池。用 P、V 操作描述它们之间的同步关系。

公用信号量mutex1;mutex2初值1;用于临界区互斥;
 生产者私用信号量empty1;empty2;初值是n,m指示空缓存数目;
 消费者私用信号量full1,full2;初值0;指示满缓冲区数目;
 整形量i,j,a,b初值均为0,i指示缓冲区序号头,j指示满缓冲区头指针;

semaphore mutex1 = 1, empty1 = n,  full1 = 0;
semaphore mutex2 = 1, empty2 = m, full2 = 0;

void A()
{
    while(1)
    {
        produce next product1;
        p(empty1);
        p(mutex1);
            buffer1[i] = product1;
            i = (i + 1) % n;
        v(mutex1);
        v(full1);
    }
}
 
void B()
{
    while(1)
    {
        p(full1);
        p(mutex1);
            product = buffer1[j];
            j = (j + 1) % n;
        v(mutex1);
        v(empty1);
            Consume product 
        Produce next product2;
        p(empty2);
        p(mutex2);
            buffer2[a] = product2;
            a = (a + 1) % m;
        v(mutex2);
        v(full2);
    }
}
 
void C()
{
    while(1)
    {
        p(full2);
        p(mutex2);
            product = buffer2[b];
            b = (b + 1) % m;
        v(mutex2);
        v(empty2);
        Consume the product;
    }
}
 
int main()
{
    parbegin(A(), B(), C());
}

面包师

面包师有很多面包和蛋糕,由 n 个销售人员销售。每个顾客进店后先取一个号,并且等着叫号。当一个销售人员空闲下来,就叫下一个号。请分别编写销售人员和顾客进程的程序。

面包师问题
semaphore mutex_s =1	//店员叫号互斥
semaphore mutex_c =1	//顾客取号互斥
semaphore sala = n		//店员人数
semaphore customer =0	//顾客数
int count_c =0	//顾客取号数
int count_s =0 	//店员叫号数
void customer()
{
	P(mutex_c)	//申请取号
	count_c++;	//取号
	V(mutex_c)	//释放取号资源
	V(customer)	
	P(sala)		//申请店员
	购买...
}
void salaer()
{
	P(customer)	//等待顾客
	P(mutex_s)	//申请叫号
	count_s++;	//叫号号码
	V(mutex_s)	//释放叫号资源
	服务...	
	V(sala)		//释放店员
}

睡眠的理发师问题

理发店里有一位理发师、一把理发椅和n把供等候理发的顾客坐的椅子。如果没有顾客,理发师便在理发
椅上睡觉。当一个顾客到来时,他必须先叫醒理发师,如果理发师正在理发时又有顾客来到,则如果有空
椅子可坐,他们就坐下来等;如果没有空椅子,他就离开。这里的问题是:为理发师和顾客各编写一段程
序,来描述他们行为。要求不能带有竞争条件。
用信号量和PV操作实现

睡眠的理发师
int chair =n	//椅子数
int wait =0		//	等待者数
semaphore barber =1;	//理发师状态
semaphore customer =0;	//顾客数
semaphore mutex =1;	//临界区

void barber()
{
	while(1)
	{
	P(customer)		//申请等待顾客
	P(mutex)		//申请临界区
	wait--;			//等待的顾客减一
	V(barber)		//理发师准备理发
	V(mutex)		//释放临界区
	}	
	CUT();			//理发
}

void customer()
{
	P(mutex)		//申请临界区
	if(wait<chair)	//有空位置
	{
	wait++;			//等待者加一
	V(customer)		//唤醒理发师
	V(mutex)		//释放临界
	P(barber)		//申请理发师,理发师空闲则理发,理发师忙等待
	CUT();			//理发
	}
	else
	V(mutex)		//无位置,离开
}
上一篇:Hibernate查询——HQL,包括分页查询


下一篇:Yii2.0数据库操作增删改查详解