我正在研究睡眠教授场景中的一些信号量问题。它使用计数信号量模型。以下是基本指南:
- 候诊室(关键部分(有3把椅子。教授办公室有一把椅子,每次可容纳一名学生
- 如果办公室里没有学生,教授就会睡着
- 当学生到达时,教授就会醒来。如果教授睡着了,学生就会叫醒教授
- 如果学生来到等候区,所有的椅子都被占用了,学生就会离开
- 如果教授正忙于另一位学生,但有空位等候,该学生就在其中一张空闲的椅子上等候
现在,这是我为睡眠教授问题编写的伪代码:
/* Counting semaphores - the integer value represents the initial count for the semaphores */
Semaphore students = 0; /* Number of students waiting for service */
Semaphore professor = 0; /* Number of professors waiting for students */
Semaphore mutex = 1; /* Mutual exclusion when accessing the waiting room */
int waiting = 0; /* Students waiting for turn with professor */
Professor() {
while (office hours) {
wait (students); /* Go to sleep if no students */
wait (mutex); /* Get access to waiting room */
waiting = waiting - 1; /* Decrement number of waiting students */
signal (professor); /* One professor is ready */
signal (mutex); /* Releasing waiting room */
ConsultWithStudent();
}
}
Student() {
wait (mutex); /* Enter critical section, which is the waiting room */
if (waiting < 3) { /* If there are free chairs in the waiting room */
waiting = waiting + 1;
signal (students); /* Wake up professor is necessary */
signal (mutex); /* Release access to count of waiting students */
wait (professor); /* Wait for professor if not available */
GetHelpFromProfessor();
} else {
signal (mutex); /* Waiting area is full, leave without waiting */
}
}
我已经解决了几个代码跟踪问题,我想知道我的信号量计数是否适合每一个问题:
场景1:假设教授在办公时间到达,然后一名学生到达。假设教授目前正在咨询这个学生。信号量计数如下:
信号量计数
学生1
Mutex 0
教授1
场景2:当教授与第一个学生交谈时,又有4个学生到达。显示信号量的结果计数:
信号量计数
学生1
Mutex 3
教授1
场景3:教授结束与第一个学生的谈话,该学生离开。教授开始和第二个学生交谈。当教授与第二个学生交谈时,显示信号量的结果计数:
信号量计数
学生1
Mutex 2
教授1
有人能帮我复习一下我的作品吗?是的,这是家庭作业,我在生成伪代码后试图理解信号量(https://www.geeksforgeeks.org/sleeping-barber-problem-in-process-synchronization/)我自己也有类似的理发师问题。
信号量为任意数量的许可证提供了一个结构。我认为你不需要第三个信号量"互斥"——只需要一个用于走廊的椅子,一个用于办公室的椅子。
为了把注意力集中在候诊室的三把椅子上,我会设置一个有三张许可证的信号灯;像这样在Java中:
Semaphore chairsInWaitingRoom = new Semaphore(3);
就其本身而言,在任何人被困等待之前,允许对acquire()
进行三次不同的调用,因此这条线路可以运行三次而不会阻塞:
chairsInWaitingRoom.acquire();
但是,当学生出现时,您可以拨打tryAcquire()
,而不是拨打acquire()
——如果尝试获得许可证成功与否,这将返回true/false。如果来电者收到true
,那么他们"在办公室外有一把椅子"。如果呼叫者收到false
,那么没有椅子可用(这可能包括另一名学生只是击败他们到最后一把椅子的比赛条件(。
boolean success = chairsInWaitingRoom.tryAcquire();
if (success) {
// student was able to safely get a chair
} else {
// no more chairs were available; student leaves
}
在某个时候,办公室里的一把椅子将可用,所以学生需要先买一把新椅子,然后松开他们的"走廊"椅子;可能看起来像这样:
Semaphore chairsInWaitingRoom = new Semaphore(3);
Semaphore chairInOffice = new Semaphore(1);
boolean success = chairsInWaitingRoom.tryAcquire();
if (success) {
// student was able to safely get a chair; now wait for the main office chair
chairInOffice.acquire(); // first get the new office seat, block here
chairsInWaitingRoom.release(); // then give up your hallway chair
} else {
// no more chairs were available; student leaves
}