如果在条件x上挂起了多个进程,并且某个进程执行了x.signal()操作,那么我们可以确定哪个挂起的进程接下来应该通过一个简单的解决方案恢复,即先使用先到先得。服务(FCFS)排序,以便首先恢复等待时间最长的进程。然而,在许多情况下,这种简单的调度方案是不够的。因此,可以使用条件等待构造。该构造具有以下形式
x.wait(c);
这里c是一个整数表达式,在wait()
执行该操作时将对其求值。然后,将c的值(称为优先级数字)与挂起的进程的名称一起存储。当执行x.signal()时,具有最小优先级编号的进程将继续执行。为了说明这种新机制,请请看以下代码中所示的ResourceAllocator监视器,该监视器控制竞争进程之间单个资源的分配。
monitor ResourceAllocator{ boolean busy; condition x; void acquire(int time){ if (busy) x.wait(time); busy = true; } void release(){ busy = false; x.signal(); } initialization code(){ busy = false; } }
每个进程都要求分配此资源时,请指定计划使用该资源的最长时间。监视器将资源分配给时间分配请求最短的进程。需要访问上述问题中的资源的进程必须遵循以下顺序-
R.acquire(t); ... access the resource; … R.release();
其中R是ResourceAllocator类型的实例。
监控器概念无法保证将遵守前面的访问顺序,但是,不幸的是,可能会发生以下问题-
在没有先获得对资源的访问权限的情况下,进程可能会访问资源。
一旦授予了对资源的访问权限,该进程可能永远不会释放资源。
进程可能尝试释放从未请求的资源。
一个进程可能两次请求同一资源(而没有先释放该资源)。
解决当前问题的一种可能解决方案是在ResourceAllocator监视器中包括资源访问操作。但是,使用此解决方案将意味着根据内置的监视器调度算法而不是我们已编码的算法来进行调度。
我们必须检查所有使用ResourceAllocator监视器及其托管资源的程序,以确保进程遵守适当的顺序。建立该系统的正确性必须满足两个条件。首先,用户进程必须始终按正确的顺序在监视器上进行调用,其次,必须确保不合作的进程不会简单地忽略监视器提供的互斥网关并尝试访问共享资源直接使用,而不使用访问协议。只有确保这两个条件,我们才能保证不会发生与时间有关的错误,并且不会破坏调度算法。