原文:
现在回到竞争条件的问题。这里有可能会出现竞争条件,其原因是对count的访问未加限制。有可能出现以下情况:缓冲区为空,消费者刚刚读取count的值发现它为0。此时调度程序决定暂停消费者并启动运行生产者。生产者向缓冲区中加入一个数据项,count加1。现在count的值变成了1。它推断认为由于count刚才为0,所以消费者此时一定在睡眠,于是生产者调用wakeup来唤醒消费者。
但是,消费者此时在逻辑上并未睡眠,所以wakeup信号丢失。当消费者下次运行时,它将测试先前读到的count值,发现它为0,于是睡眠。生产者迟早会填满整个缓冲区,然后睡眠。这样一来,两个进程都将永远睡眠下去。
在这里“逻辑上”是指当消费者进程检测到count等于0时,在还没有运行sleep()时消费者进程时间片到期,消费者进程变成runnable状态,生产者这时候被调度运行,当count变为1时,生产者试图唤醒消费者,此时对于消费者来说唤醒是无效的,因为消费者根本没有运行到sleep(),,wakeup信号丢失,所以说在逻辑上并未睡眠。当时间片被转到消费者时,这时候消费者进程被调度,执行完sleep()后,消费者进程才真正进入逻辑上得睡眠。尽管count已经非零了,但是再也不会有唤醒信号了,它将永远沉睡。归根到底是因为这里对count的访问不是原子性的。