在操作系统中,使用PV操作对进程中的临界区进行同步与互斥。PV操作都是一个原语,是不会被打断的。PV操作针对的是信号量,所谓信号量,就是记录某信号当前状态的一个量。
从直观上来理解,P操作就是测试信号量S的是否有资源,若没有,则加入到S的等待队列中;V操作就是释放对S的资源,并唤醒S的等待队列中的第一个进程。
一般来说,比较经典的互斥与同步的问题有:生产者与消费者问题,读者写者问题,哲学家就餐问题,巴拿马运河问题,等等。下面对这些问题进行分析。
生产者与消费者问题,现在考虑最简单的情况,只有一个生产者和一个消费者,且只有一个缓冲区,那么,消费者必须在生产者生产后(缓冲区非空)才能取产品消费,即他们之间是同步的关系;生产者生产后必须在缓冲区未满时送出产品;那么,定义一个信号量S1(初值为0)来标识缓冲区非空,信号量S2(初值为1)来标识缓冲区非满。
对于消费者,其操作为:
while(true)
{
P(S1);
取产品;
V(S2);
消费
}
对于生产者,其操作为:
while(true)
{
消费;
P(S2);
送产品;
V(S1);
}
当然,这是最简单的生产者与消费者问题,在大多数情况下,生产者和消费者往往是多个的,缓冲也是多个的,那么,就需要加入互斥的操作,会稍微复杂一点,在此不再赘述。
读者写者问题是这样的,有一群写者和一群读者,写者在写同一本书,读者也在读这本书,多个读者可以同时读这本书,但是,只能有一个写者在写书,并且,读者必写者优先,也就是说,读者和写者同时提出请求时,读者优先。当读者提出请求时需要有一个互斥操作,另外,需要有一个信号量S来当前是否可操作。
对于读者,其操作为:
while(true)
{
P(mutex);
readCount++
if(readCount==1)
P(S);
V(mutex);
读书
P(mutex);
readCount--;
if(readCount==1)
V(S);
V(mutex);
}
对于写者,其操作为:
while(true)
{
P(S);
写;
V(S);
}
关于哲学家就餐问题和巴拿马问题,也都是很经典的问题,限于时间问题,笔者不准备再做详细的分析。
总之,PV操作在进程的同步于互斥中起着至关重要的作用,在多线程的编程中也是经常会用到。
发表于 @ 2006年11月26日 22:37:00|评论(loading...)|编辑