我正在研究“沉睡教授”场景中的一些信号量问题。它使用计数信号量模型。这些是基本准则:


候诊室(关键区域)有3张椅子。教授的办公室有1张椅子,一次可容纳一名学生。
如果办公室里没有学生,教授将入睡。
学生到达时,教授将醒来。如果教授睡着了,学生将唤醒教授。
如果学生来到等候区并且所有椅子都被占用,则学生离开。
如果教授正忙于另一个学生,但有可用的等待空间,则该学生将在其中一张免费椅子中等待。


现在,这是我为“沉睡教授问题”编写的伪代码:

/* 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

互斥0

教授1

方案2:当教授与第一位学生交谈时,又有4位学生到达。显示信号量的结果计数:

信号量计数

学生1

互斥体3

教授1

方案3:教授结束了与第一个学生的交谈,然后那个学生离开。教授开始与第二名学生谈话。在教授与第二位学生交谈时,显示信号量的最终计数:

信号量计数

学生1

互斥体2

教授1

有人可以帮我复习我的作品吗?是的,这是用于家庭作业,在尝试自己从类似理发师问题生成伪代码(https://www.geeksforgeeks.org/sleeping-barber-problem-in-process-synchronization/)之后,我试图理解信号量。

最佳答案

信号量为任意数量的许可提供了一种结构。我认为您不需要在混合中使用第三个信号量“互斥体”-仅一个用于走廊中的椅子,一个用于办公室中的椅子。

为了专注于等候室中的三把椅子,我将设置一个带有三个许可证的信号灯。在Java中是这样的:

Semaphore chairsInWaitingRoom = new Semaphore(3);


就其本身而言,在任何人陷入等待之前,允许对acquire()进行三个不同的调用,因此该行可以运行三次而不会阻塞:

chairsInWaitingRoom.acquire();


但是,您可以呼叫acquire()而不是在学生出现时呼叫tryAcquire()-如果成功获取许可的尝试成功或失败,它将返回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
}

10-08 01:58