生产者—消费者问题

问题描述

系统中有一组生产者进程和一组消费者进程,生产者进程每次生产一个产品放入缓冲区,消费者进程每次从缓冲区取出一个产品并使用。(这里的"产品"理解为某种数据)

生产者、消费者共享一个初始为空、大小为n的缓冲区。

只有缓冲区没满时,生产者才能把产品放入缓冲区,否则必须等待。

只有缓冲去是临界资源,各进程必须互斥地访问。

semaphore mutex = 1;    //互斥信号量,实现对缓冲区的互斥访问
semaphore empty = n;    //同步信号量,表示空闲缓冲区的数量
semaphore full = 0;     //同步信号量,表示产品的数量,也即非缓冲区的数量
producer() {
    while(1) {
        生产一个产品;
        P(empty);    //消耗一个空闲缓冲区
        P(mutex);    //实现互斥
        把产品放入缓冲区;
        V(mutex);
        V(full);     //增加一个产品
    }
consumer() {
    while(1) {
        P(full);        //消耗一个产品
        P(mutex);
        从缓冲区取出一个产品;
        V(mutex);    
        V(empty);       //增加一个空闲缓冲区
        使用产品
    }
}

能否改变相邻P、V操作的顺序?

producer() {
    while(1) {
        生产一个产品;
        P(mutex);        1
        P(empty);        2
        把产品放入缓冲区;
        V(mutex);
        V(full);
    }
}
consumer() {
    while(1) {
        P(mutex);    3
        P(full);     4
        从缓冲区取出一个产品
        V(mutex);
        V(empty);
        使用产品
    }
}

若此时缓冲区已经放慢了产品,则empty = 0,full = n。

则生产者进程执行 1 使mutex变为0,再执行 2 ,由于已经没有空闲缓冲区,因此生产者被阻塞。由于生产者阻塞,因此切换回消费者进程。消费者进程执行 3 ,由于mutex为0,即生产者还没释放对临界资源的"锁",因此消费者也被阻塞。

这就造成了生产者等待消费者释放空闲缓冲区,而消费者又等待生产者释放临界区的情况,生产者和消费者循环等待被对方唤醒,出现"死锁"。

同样的,若缓冲区中没有产品,即full = 0,empty = n。按 3、4、1的顺序执行就会发生死锁。

因此,实现互斥的P操作一定要在实现同步的P操作之后。

V操作不会导致进程阻塞,因此两个V操作顺序可以交换。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值