读写器的信号量解决方案:更新读取器计数和等待读取/写入二进制信号量之间的顺序?

时间:2017-10-23 03:09:20

标签: multithreading concurrency synchronization computer-science semaphore

来自操作系统概念

  

在第一个读者 - 作家问题的解决方案中,读者   进程共享以下数据结构:

semaphore rw mutex = 1;
semaphore mutex = 1;
int read_count = 0;

do {
wait(rw_mutex);
. . .
/* writing is performed */
. . .
signal(rw_mutex);
} while (true);
     

图5.11编写过程的结构。

do {
wait(mutex);
read count++;
if (read_count == 1)
    wait(rw mutex);
signal(mutex);
. . .
/* reading is performed */
. . .
wait(mutex);
read count--;
if (read_count == 0)
    signal(rw_mutex);
signal(mutex);
} while (true);
     

图5.12读者过程的结构。

     

信号量mutexrw_mutex初始化为1;读数   初始化为0.信号量rw_mutex对两者都是通用的   读者和作者的过程。 mutex信号量用于确保   更新变量读取计数时的互斥。阅读   count变量跟踪当前正在读取的进程数   物体。信号量rw_mutex用作互斥   作家的信号量。它也被第一个或最后一个读者使用   进入或退出关键部分。它不被读者使用   在其他读者处于关键部分时进入或退出的人。

  1. wait为什么signal / rw_mutex mutex由信号量read_count保护?
  2. 在读者进程的结构中,我可以在两者之间切换顺序 在wait上更新signalrw_mutex / do { wait(mutex); if (read_count == 0) wait(rw_mutex); read count++; signal(mutex); . . . /* reading is performed */ . . . wait(mutex); if (read_count == 1) signal(rw_mutex); read count--; signal(mutex); } while (true); ,如 以下

    public static boolean checkPass(String s) {
        Pattern p = Pattern.compile("[bB]{2}[0-9]{4};
        return p.matcher(s).find();
    }
    
    public static void main(String[] args) {
    
        String inputMessage = "Enter a code to validate: ";
        String userInput = " ";
        Scanner input = new Scanner(System.in);
    
        System.out.println(inputMessage);
        userInput = input.nextLine(); 
    
        while (userInput.length() != 6 || !checkPass(userInput)) {
    
        if (userInput.charAt(0)!= 'b')
            System.out.println("First Character is not a b or a B");
        if (userInput.charAt(1)!= 'b')
            System.out.println("Second character is not a b or B");
        if (!Character.isDigit(userInput.charAt(2)))
            System.out.println("Third character is not digit");
    
            System.out.println("Code: " + userInput + " is not valid");
                userInput = input.nextLine();
        }
    
    
    
        System.out.println("code: " + userInput + " is valid");
    
    
    
    }
    
  3. 感谢。

1 个答案:

答案 0 :(得分:1)

  
      
  1. wait为什么signal / rw_mutex mutex由信号量read_count保护?
  2.   

想象一下它不是,即只有read_count行被保护,并且你有读者线程α和β。

α增加signal(mutex),执行if (read_count == 1),然后执行mutex,然后 - bah! - CPU调度程序决定“足够,让其他线程也有乐趣!”,并开始执行线程β。

线程β锁定read_count,增加mutex,释放if (read_count == 1),并开始执行rw_mutex。现在,因为read_count是2,所以两个线程中的比较都失败了,所以没有读者接受read_count,而你的作者正在写入正在读取的数据。

  
      
  1. 在阅读器流程的结构中,我可以在wait上更新signalrw_mutex / read_count之间切换顺序,如下所示吗?
  2.   

是的,你可以。区别纯粹是语义上的:原始读物为“我们即将阅读,所以增加rw_mutex,如果我们是唯一的读者,请锁定read_count。执行阅读。然后,在我们完成后,减少rw_mutex,如果我们是最后一位读者,请解锁rw_mutex

如果没有人读取,您的变体将显示为“,锁定read_count。然后增加rw_mutex。执行阅读。然后,如果我们是唯一的读者,请解锁read_countsignal(rw_mutex)

尽管如此,如果作者使用了您的变体,我对第一个问题的回答会更长一些,因为另外,在使用dumps的代码部分,您可以陷入僵局:Ь

此外,概念作者在C ++中描述的是std::shared_mutex