Mesa管程的出现主要是针对了Hoare管程的一个缺点。Hoare管程是p进程唤醒了q,然后p进程去等待,让q进程执行 这样就会引起一次进程的切换,因为p进程要等待让q进程上CPU执行, 当q进程执行完了,然后再把p进程调度上CPU, p进程再来一次切换,所以Hoare管程会导致两次额外的进程切换。因为有着这样的多余开销,MESA管程提供了一种解决思路,p进程唤醒了q,然后p进程继续执行并不等待q执行,q进入等待队列准备在未来某一时刻执行。

Hoare管程用的是signal,而Mesa管程使用notify。notify是当一个进程正在管程当中,这个进程在条件变量x上执行了notify,这个操作就会使得等在x条件变量上的某个进程得到了一个通知[相当于把它唤醒]。 发信号的这个进程还是继续执行[也就是执行notify的这个进程继续执行]。所以位于条件队列的第一个进程得到了通知使得它在将来某个合适的时候,当处理机可用的时候,就会执行。但是只是得到了通知,没有马上去执行,因此由于它不是马上执行就不能保证在它下一次上CPU的时候,那个条件还依然成立,所以它要重新检查这个条件是不是成立。

当一个进程检查条件不成立的时候,进入了条件队列里等待,当另外一个进程给它发了一个通知之后,这个进程就可以得到通知,然后重新执行。重新检查条件使用while循环来取代if语句。

我们还可以进行一些改进,比如说对notify做一个非常有实用价值的改进就是给每个条件关联一个监视计时器,就是说它进入了条件这个变量队列以后,不管它是不是得到了通知,只要它等待的时间超过了一个时间量的时候,就是超时了,那就把它都进入了一个就绪态,原来在条件变量等待,就让它进入就绪态。

我们再把notify改进,就引入broadcast。notify是一次通知一个进程,而broadcast通知所有等在这个条件变量上的进程都被释放进入就绪队列。当一个进程它不知道有多少个进程将被激活的时候,用这种broadcast就比较合适,反正全部释放,你们重新进入就绪,然后你们上CPU之后重新检查条件,也不会引起其他的问题。比如生产者消费者问题,生产者生产了很多个资源,他也不知道有多少个消费者可能消费这些资源,就通知全部消费者,让他们自行检查条件然后消耗资源直到资源消耗完成。