📜  门| GATE CS 2012 |问题18(1)

📅  最后修改于: 2023-12-03 15:28:37.764000             🧑  作者: Mango

门| GATE CS 2012 |问题18

本篇为 GATE (Graduate Aptitude Test in Engineering) 计算机科学考试 2012 年的第 18 题。该问题属于操作系统课程,主要涉及进程同步和信号量。

题目描述

考虑如下的代码片段:

semaphore mutex = 1;
semaphore wrt = 1;
int readcount = 0;

void writer(void) {
    while (true) {
        down(&wrt);
        /* writing is performed */
        up(&wrt);
    }
}

void reader(void) {
    while (true) {
        down(&mutex);
        readcount++;
        if (readcount == 1)
            down(&wrt);
        up(&mutex);
        /* reading is performed */
        down(&mutex);
        readcount--;
        if (readcount == 0)
            up(&wrt);
        up(&mutex);
    }
}

其中 downup 是 P(s) 和 V(s) 操作,分别表示将信号量 s 减 1 和加 1。

关于这段代码,有以下问题:

  1. 此代码中有什么错误?
  2. 该代码段是用来干什么的?
  3. 解决该错误的最佳方法是什么?
问题分析

首先来理解一下这段代码的作用。上述代码片段是用来模拟读者-写者问题的,其中 writerreader 分别表示写者和读者的函数。在读者和写者中,都有一段加锁的代码,指的是 down(&mutex) 后面的代码。该操作的目的是为了保证在此期间,其他读者或者写者不会执行加锁代码之后的操作。在读者中,为了保证只有一个写者在操作共享资源时,会先执行 if (readcount == 1) down(&wrt);,其中 readcount 表示已经有多少个读者进入了临界区,只有当 readcount = 1 时,才会一次性地将 wrt 的信号量减 1,以此使其他的写者不能同时写。

然而,这段代码存在以下错误:

  1. 写者和读者都没有设置循环退出条件,会一直执行下去。
  2. readcount 的初始值没有设置,不确定初始情况下是否有读者在操作共享资源。
解决方案
  1. 给写者和读者设置退出条件,避免死循环。可能的退出条件包括:规定程序执行时间或者接收到终止信号。
  2. readcount 设置初始值,避免未预料到的操作。
最佳实践

除了上述的常见错误之外,关于读者-写者问题,还存在以下问题:

  1. 在高并发的情况下,可能会出现读者饥饿和写者饥饿问题。为了避免这种现象,可以采用优先队列等算法,尽量保证每个读者和写者都有机会访问共享资源。
  2. 在不同的操作系统和编译器上,对于信号量的实现可能存在差别,有可能会导致代码的错误。为了避免这种问题,可以使用操作系统或者编程语言提供的高级同步机制,如管程或者互斥锁等。

总之,在编写复杂的并发程序时,需要更加细致地考虑并发访问的情况,避免死锁、饥饿等问题的发生,从而保证程序运行的正确性和高效性。