东南大学《操作系统》课程作业 第六章

1 - The first known correct software solution to the critical-section problem for two processes was developed by Dekker. The two processes, P0 and P1, share the following variables:

boolean flag[2]; /* initially false */
int turn;

The structure of process Pi (i == 0 or 1) is shown in the following Figure. The other process is Pj (j == 1 or 0). Prove that the algorithm satisfies all three requirements for the critical-section problem.

while (true) {
  flag[i] = true;
  while (flag[j]) {
  if (turn == j) {
    flag[i] = false;
  while (turn == j)
    ; /* do nothing */
  flag[i] = true;
  }
}
/* critical section */
  turn = j;
  flag[i] = false;
/* remainder section */
}

该算法满足三条要求。
(1)互斥。Pi在进入临界区前,会等待直到turn为自己。Pi在退出临界区后,会将turn交还给Pj。这样,自己的flag只会在turn为自己时才会成功修改,实现了互斥。
(2)进步。Pi退出临界区后,会将turn交还给Pj。如果Pi要再次进入临界区,必须等Pj释放turn。这样便实现了进步,选择Pj进入临界区不会无限推迟。
(3)有限等待。该算法每次进入临界区的进程由turn决定,而turn会在每次退出临界区时发生交还,因此Pi与Pj会轮流获得turn的许可,不会发生无限等待。

2 - Explain why implementing synchronization primitives by disabling interrupts is not appropriate in a single-processor system if the synchronization primitives are to be used in user-level programs.
如果用户级程序可以禁用中断,则它可以关闭用于指示上下文切换的中断,造成上下文切换不发生,从而无法进行处理器上的进程切换。

3 - Explain why interrupts are not appropriate for implementing synchronization primitives in multiprocessor systems.
利用中断在多处理器系统上实现同步原语是不合适的。需要同步的进程只能关闭在当前处理器上的中断(关闭所有处理器的中断很困难,也会严重影响性能),使得在当前处理器上运行的其他进程不会与该进程发生同步问题,但无法保证在其他处理器上运行的进程与该进程保持互斥。

4 - Servers can be designed to limit the number of open connections. For example, a server may wish to have only N socket connections at any point in time. As soon as N connections are made, the server will not accept another incoming connection until an existing connection is released. Explain how semaphores can be used by a server to limit the number of concurrent connections.
定义信号量,初始化为N。每当有新客户端接入时,调用wait占据一个信号量,如果当前信号量数量小于等于0,则不断等待;每当有客户端退出时,调用signal释放一个信号量。

5 - Show that, if the wait() and signal() semaphore operations are not executed atomically, then mutual exclusion may be violated.
以wait为例,如果它的执行不是原子性的,假设当前信号量为1,两个进程可能同时发现这一情况,并将信号量减1,认为自己申请到了信号量。这将破坏互斥性。

6 - The Sleeping-Barber Problem. A barbershop consists of a waiting room with n chairs and a barber room with one barber chair. If there are no customers to be served, the barber goes to sleep. If a customer enters the barbershop and all chairs are occupied, then the customer leaves the shop. If the barber is busy but chairs are available, then the customer sits in one of the free chairs. If the barber is asleep, the customer wakes up the barber. Write a program to coordinate the barber and the customers.
可以用信号量方法描述该问题。对于顾客,有两个资源,一是n把chairs,二是1位barber。对于理发师,有一个资源,即等待理发的顾客,当没有这个资源时,理发师睡眠。另外,对于临界区资源people的修改必须是互斥的。

semaphore barber = 1; // 理发师信号量
semaphore chair = 0; // 已用的等待椅信号量
semaphore mutex = 1; // 互斥信号量
int people = 0; // 数据,等待理发的顾客数
// 理发师进程
void barber() {
  while (true) {
    wait(chair); // 理发师等待顾客,没有顾客就睡觉
    wait(mutex); // 准备服务顾客,进入临界区
    people -= 1; // 修改临界区数据
    signal(mutex); // 释放
    /* 进行理发 */
    signal(barber); // 理发完了
  }
}
// 顾客进程
void customer() {
  wait(mutex); // 进入临界区
  if (people < n) {
    people += 1; // 还有空位,就坐进去
    signal(mutex); // 完成临界区数据修改
    signal(chair); // 如果理发师在睡觉,就叫醒他
    wait(barber); // 等待理发师资源(可能正在给别人理发)
    /* 进行理发 */
  } else {
    signal(mutex); // 没有空位,不能进店
  } 
}

7 - Write a bounded-buffer monitor in which the buffers (portions) are embedded within the monitor itself.
我们用一个简单的生产者-消费者模型作为管程提供的功能。

monitor BoundedBuffer {
  DataType buffer[BUF_LEN];
  int pointer = 0;
  condition x, y;
  void produce(DataType val) {
    while (pointer == BUF_LEN) x.wait(); // 缓冲区满,挂起x
    buffer[pointer++] = val;
    y.signal(); // 唤醒y
  }
  DataType consume() {
    while (pointer == 0) y.wait(); // 缓冲区空,挂起y
    DataType val = buffer[--pointer];
    x.signal(); // 唤醒x
    return val;
  }
}

8 - How does the signal() operation associated with monitors differ from the corresponding operation defined for semaphores?
管程的signal调用时,如果没有挂起进程,就没有作用;信号量的signal调用时,总会增加该信号量的值,供后续进程使用。

9 - Consider a system consisting of processes P1, P2, ..., Pn, each of which has a unique priority number. Write a monitor that allocates three identical line printers to these processes, using the priority numbers for deciding the order of allocation.

monitor ThreePrinters {
  int nAvailablePrinter = 3;
  Process queuedProccess[PROC_COUNT]; // Process: {pid:int, priority: int}
  int nQueuedProcess = 0;
  condition x;

  void acquirePrinter(Process process) {
    if (nAvailablePrinter > 0) {
      nAvailablePrinter -= 1;
      return; // 如果有空余打印机,直接分配
    }
    // 否则进入等待队列,按优先级分配
    queuedProcess[nQueuedProcess++] = process;
    sort(queuedProcess, /* 优先级降序排列 */);
    while (nAvailablePrinter == 0 || queuedProcess[0] != process) {
      x.wait(); // 没有空余打印机,或者有但是还没轮到自己,就挂起
    }
    // 将队首出队,分配打印机
    queuedProcess[0] = queuedProcess[nQueuedProcess – 1];
    nQueuedProcess -= 1;
    nAvailablePrinter -= 1;
    // 更新队列
    sort(queuedProcess, /* 优先级降序排列 */);
  }

  void releasePrinter() {
    nAvailablePrinter += 1;
    x.signal(); // 唤醒x
  }
}
原文地址:https://www.cnblogs.com/zxuuu/p/15631226.html