现代操作系统-进程间通信
如何避免竞争条件:
1.任何两个进程不能同时处于其临界区
2.不应对CPU的速度和数量做任何假设
3.临界区外运行的进程不得阻塞其他进程
4.不得使进程无限期等待进入临界区
生产者-消费者问题:
两个进程共享一个公共的固定大小的缓冲区,其中一个是生产者,将信息放入缓冲区,另一个是消费者,从缓冲区中取出信息。
问题在于当缓冲区已满,而生产者还想放入一个新的数据,解决方法是让生产者休眠,直到消费者取出一个时唤醒。反之亦然,当消费者试图从缓冲区取数据而缓冲区为0时,消费者休眠。
该方法存在竞争条件的问题,如果缓冲区最多存放N个数据,则生产者首先判断是否为N,若是,则生产者休眠,否则生产者生成一个数据放入缓冲区。消费者类似。
因此会出现竞争条件,对于数据的访问未加限制,有可能出现以下情况:缓冲区为0,消费者刚刚读取为0,因此暂停消费者并启动生产者,加入数据,变为1,生产者认为由于缓冲区为0,消费者一定处于睡眠,会调用weak up来唤醒消费者。但消费者实际上未处于睡眠,weak up信号丢失,当消费者下次运行时,将测试先前读到的数据发现为0,于是睡眠,生产者迟早会填满整个缓冲区然后睡眠,因此两个进程都将永远睡眠下去。
问题的实质在于发给一个未睡眠进程的weakup信号丢失,若没有丢失,则一切正常。一种快速的方法是加上一个唤醒等待位,若一个wakeup信号发送给一个清醒的进程信号时,将该位置1,随后当进程要休眠时,若唤醒等待位为1,则将该位清除,而该进程仍保持清醒。
但是若有更多进程,一个唤醒等待位就不够了,那么可以加入多个等待位,但这并没有从根本上解决问题。
根本上解决生产者消费者问题的方法是引用信号量
信号量的取值可以为0(表示没有保存下来的唤醒操作),也可以为正值(表示多个唤醒操作)。
信号量有两种操作,down(P)和up(V),分别为一般化后的sleep和wakeup,对一信号量执行down操作,则是检查其值是否大于0,若大于0,则减1,用掉一个保存的唤醒信号,若该值为0,则进程将睡眠。up操作是对信号量的值增1。
也就是说,信号量是提供了多个进程对于一个共享数据的访问保护,使进程按照顺序排队访问。
如果不需要信号量的计数能力,也可以使用简化版本,互斥量。
posted on 2018-04-06 17:54 sichenzhao 阅读(147) 评论(0) 编辑 收藏 举报