标题：PV操作
简介
1962年，狄克斯特拉离开数学中心进入位于荷兰南部的艾恩德霍芬技术大学(Eindhoven Technical University）任数学教授。在这里，他参加了X8计算机的开发，设计与实现了具有多道程序运行能力的操作系统——THE Multiprogramming System。
详细资料
THE是艾恩德霍芬技术大学的荷兰文Tchnische Hoogeschool Eindhov –en的词头缩写。狄克斯特拉在THE这个系统中所提出的一系统方法和技术奠定了计算机现代操作系统的基础，尤其是关于多层体系结构，顺序进程之间的同步和互斥机制这样一些重要的思想和概念都是狄克斯特拉在THE中首先提出并为以后的操作系统如UNⅨ等所采用的。为了在单处理机的情况下确定进程(process）能否占有处理机，狄克斯特拉将每个进程分为“就绪”（ready）、“运行”（running）和“阻塞”（blocking）三个工作状态。由于在任一时刻最多只有一个进程可以使用处理机，正占用着处理机的进程称为“运行”进程。当某进程已具备了使用处理机的条件，而当前又没有处理机供其使用，则使该进程处于“就绪”状态。当运行进程由于某种原因无法继续运行下去时，就停止其占用处理机，使之进入“阻塞”状态，待造成其退出运行的条件解除，再进入“就绪”状态。而对系统中所有同时运行的进程（及并行），（在一个进程访问共享数据时，另一个进程不访问该数据）和互斥（mutually- exclusive，指两个进程不能同时在一个临界区中使用同一个可重复使用的资源，诸如读写缓冲区）两个关系，狄克斯特拉巧妙地利用火车运行控制系统中的“信号灯”（semaphore，或叫“信号量”）概念加以解决。所谓信号灯，实际上就是用来控制进程状态的一个代表某一资源的存储单元。例如，P1和P2是分别将数据送入缓冲B和从缓冲B读出数据的两个进程，为了防止这两个进程并发时产生错误，狄克斯特拉设计了一种同步机制叫“PV操作”，P操作和V操作是执行时不被打断的两个操作系统原语。执行P操作P（S）时信号量S的值减1，若结果不为负则P（S）执行完毕，否则执行P操作的进程暂停以等待释放。执行V操作V（S）时，S的值加1，若结果不大于0则释放一个因执行P（S）而等待的进程。对P1和P2可定义两个信号量S1和S2，初值分别为1和0。进程P1在向缓冲B送入数据前执行P操作P（S1），在送入数据后执行V操作V（S2）。进程P2在从缓冲B读取数据前先执行P操作P（S2），在读出数据后执行V操作V（S1）。当P1往缓冲B送入一数据后信号量S1之值变为0，在该数据读出后S1之值才又变为1，因此在前一数未读出前后一数不会送入，从而保证了P1和P2之间的同步。中国读者常常不明白这一同步机制为什么叫PV操作，原来这是狄克斯特拉用荷兰文定义的，因为在荷兰文中，通过叫passeren，释放叫vrijgeven，PV操作因此得名。这是在计算机术语中不是用英语表达的极少数的例子之一。
解释
1962年，狄克斯特拉离开数学中心进入位于荷兰南部的艾恩德霍芬技术大学(Eindhoven Technical University）任数学教授。在这里，他参加了X8计算机的开发，设计与实现了具有多道程序运行能力的操作系统——THE Multiprogramming System。THE是艾恩德霍芬技术大学的荷兰文Tchnische Hoogeschool Eindhov –en的词头缩写。狄克斯特拉在THE这个系统中所提出的一系统方法和技术奠定了计算机现代操作系统的基础，尤其是关于多层体系结构，顺序进程之间的同步和互斥机制这样一些重要的思想和概念都是狄克斯特拉在THE中首先提出并为以后的操作系统如UNⅨ等所采用的。为了在单处理机的情况下确定进程（process）能否占有处理机，狄克斯特拉将每个进程分为“就绪”（ready）、“运行”（running）和“阻塞”（blocking）三个工作状态。由于在任一时刻最多只有一个进程可以使用处理机，正占用着处理机的进程称为“运行”进程。当某进程已具备了使用处理机的条件，而当前又没有处理机供其使用，则使该进程处于“就绪”状态。当运行进程由于某种原因无法继续运行下去时，就停止其占用处理机，使之进入“阻塞”状态，待造成其退出运行的条件解除，再进入“就绪”状态。而对系统中所有同时运行的进程，在一个进程访问共享数据时，另一个进程不访问该数据）和互斥（mutually- exclusive，指两个进程不能同时在一个临界区中使用同一个可重复使用的资源，诸如读写缓冲区）两个关系，狄克斯特拉巧妙地利用火车运行控制系统中的“信号灯”（semaphore，或叫”信号量”）概念加以解决。所谓信号灯，实际上就是用来控制进程状态的一个代表某一资源的存储单元。例如，P1和P2是分别将数据送入缓冲B和从缓冲B读出数据的两个进程，为了防止这两个进程并发时产生错误，狄克斯特拉设计了一种同步机制叫“PV操作”，P操作和V操作是执行时不被打断的两个操作系统原语。执行P操作P（S）时信号量S的值减1，若结果小于0，则P（S）执行完毕，否则执行P操作的进程暂停以等待释放。执行V操作V（S）时，S的值加1，若结果不大于0，则释放一个因执行P（S）而等待的进程。对P1和P2可定义两个信号量S1和S2，初值分别为1和0。进程P1在向缓冲B送入数据前执行P操作P（S1），在送入数据后执行V操作V（S2）。进程P2在从缓冲B读取数据前先执行P操作P（S2），在读出数据后执行V操作V（S1）。当P1往缓冲B送入一数据后信号量S1之值变为0，在该数据读出后S1之值才又变为1，因此在前一数未读出前后一数不会送入，从而保证了P1和P2之间的同步。中国读者常常不明白这一同步机制为什么叫PV操作，原来这是狄克斯特拉用荷兰文定义的，因为在荷兰文中，通过叫passeren，释放叫vrijgeven，PV操作因此得名。这是在计算机术语中不是用英语表达的极少数的例子之一。信号量 
信号量是最早出现的用来解决进程同步与互斥问题的机制， 
包括一个称为信号量的变量及对它进行的两个原语操作。
信号量的概念1．信号量的类型定义 
信号量（semaphore）的数据结构为一个值和一个指针，指针指向等待该信号量的下一个进程。信号量的值与相应资源的使用情况有关。当它的值大于0时，表示当前可用资源的数量；当它的值小于0时，其绝对值表示等待使用该资源的进程个数。注意，信号量的值仅能由PV操作来改变。
一般来说，信号量S>=0时，S表示可用资源的数量。执行一次P操作意味着请求分配一个单位资源，因此S的值减1；当S<0时，表示已经没有可用资源，请求者必须等待别的进程释放该类资源，它才能运行下去。而执行一个V操作意味着释放一个单位资源，因此S的值加1；若S<0，表示有某些进程正在等待该资源，因此要唤醒一个等待状态的进程，使之运行下去。
2．PV原语
PV操作是典型的同步机制之一。用一个信号量与一个消息联系起来，当信号量的值为0时，表示期望的消息尚未产生；当信号量的值非0时，表示期望的消息已经存在。用PV操作实现进程同步时，调用P操作测试消息是否到达，调用V操作发送消息。
对一个信号量变量可以进行两种原语操作：p操作和v操作，定义如下：procedure p(var s:samephore); 
{ 
s.value=s.value-1; 
if (s.value<0) asleep(s.queue); 
} 
procedure v(var s:samephore); 
{ 
s.value=s.value+1; 
if (s.value<=0) wakeup(s.queue); 
} 
其中用到两个标准过程：
asleep(s.queue）；执行此操作的进程的PCB进入s.queue尾部，进程变成等待状态 
wakeup(s.queue）；将s.queue头进程唤醒插入就绪队列
s.value初值为1时，可以用来实现进程的互斥。
p操作和v操作是不可中断的程序段，称为原语。如果将信号量看作共享变量，则pv操作为其临界区，多个进程不能同时执行，一般用硬件方法保证。一个信号量只能置一次初值，以后只能对之进行p操作或v操作。
由此也可以看到，信号量机制必须有公共内存，不能用于分布式操作系统，这是它最大的弱点。
V原语的主要操作是：
⑴sem加1； 
⑵若相加结果大于零，则进程继续执行； 
⑶若相加结果小于或等于零，则唤醒一阻塞在该信号量上的进程，然后再返回原进程继续执行或转进程调度。
利用信号量和PV操作实现进程互斥的一般模型是：
进程P1 进程P2 …… 进程Pn
……　 ……　 ……
P（S）；　 P（S）；　 P（S）；
临界区；　 临界区；　 临界区；
V（S）；　 V（S）；　 V（S）；
……　 ……　 …… ……
其中信号量S用于互斥，初值为1。
使用PV操作实现进程互斥时应该注意的是：
⑴每个程序中用户实现互斥的P、V操作必须成对出现，先做P操作，进临界区，后做V操作，出临界区。若有多个分支，要认真检查其成对性。
⑵P、V操作应分别紧靠临界区的头尾部，临界区的代码应尽可能短，不能有死循环。
⑶互斥信号量的初值一般为1。
利用信号量和PV操作实现进程同步：
PV操作是典型的同步机制之一。用一个信号量与一个消息联系起来，当信号量的值为0时，表示期望的消息尚未产生；当信号量的值非0时，表示期望的消息已经存在。用PV操作实现进程同步时，调用P操作测试消息是否到达，调用V操作发送消息。
使用PV操作实现进程同步时应该注意的是：
⑴分析进程间的制约关系，确定信号量种类。在保持进程间有正确的同步关系情况下，哪个进程先执行，哪些进程后执行，彼此间通过什么资源（信号量）进行协调，从而明确要设置哪些信号量。
⑵信号量的初值与相应资源的数量有关，也与P、V操作在程序代码中出现的位置有关。
⑶同一信号量的P、V操作要成对出现，但它们分别在不同的进程代码中。
典型理解偏差三个问题：
一，以V原语的1、2步来做，Sem不就永远大于0，那进程不就一直循环执行成为死循环了？ 
二，Sem大于0那就表示有临界资源可供使用，为什么不唤醒进程？ 
三，Sem小于0应该是说没有临界资源可供使用，为什么还要唤醒进程？ 
析疑：
一，P操作对sem减1的。P、V原语必须成对使用！从而不会造成死循环。
二，Sem大于0的确表示有临界资源可供使用，而且这个时候没有进程被阻塞在这个资源上，也就是说没有进程因为得不到这类资源而阻塞，所以没有被阻塞的进程，自然不需要唤醒。
三，V原语操作的本质在于：一个进程使用完临界资源后，释放临界资源，使Sem加1，以通知其它的进程，这个时候如果Sem<0，表明有进程阻塞在该类资源上，因此要从阻塞队列里唤醒一个进程来“转手”该类资源。比如，有两个某类资源，四个进程A、B、C、D要用该类资源，最开始Sem=2，当A进入，Sem=1，当B进入Sem=0，表明该类资源刚好用完， 当C进入时Sem=-1，表明有一个进程被阻塞了，D进入，Sem=-2。当A用完该类资源时，进行V操作，Sem=-1，释放该类资源，而这时Sem<0，表明有进程阻塞在该类资源上，于是唤醒一个。
为了进一步加深理解，再引入二个问题：
四，如果是互斥信号量的话，应该设置信号量Sem=1，但是当有5个进程都访问的话，最后在该信号量的链表里会有4个在等待，也是说S=-4，那么第一个进程执行了V操作使S加1，释放了资源，下一个应该能够执行，但唤醒的这个进程在执行P操作时因S〈0，也还是执行不了，这是怎么回事呢？ 
五，Sem的绝对值表示等待的进程数，同时又表示临界资源，这到底是怎么回事？
析疑：
四，当一个进程阻塞了的时候，它已经执行过了P操作，并卡在临界区那个地方。当唤醒它时就立即进入它自己的临界区，并不需要执行P操作了，当执行完了临界区的程序后，就执行V操作。
五，当信号量Sem小于0时，其绝对值表示系统中因请求该类资源而被阻塞的进程数目.S大于0时表示可用的临界资源数。注意在不同情况下所表达的含义不一样。当等于0时，表示刚好用完。