读者-写者问题

2025 年 4 月 4 日 | 阅读 9 分钟

读者-写者问题是进程同步的经典问题,它涉及到一个文件等数据集,该数据集在同一时间由多个进程共享。在这些不同的进程中,有些是读者——它们只能读取数据集;它们不执行任何更新,有些是写者——它们既可以读取也可以写入数据集。

读者-写者问题用于管理不同读者和写者进程之间的同步,以确保数据集不会出现问题,即不会产生不一致性。

让我们通过一个例子来理解——如果两个或两个以上的读者希望在同一时间访问文件,则不会出现问题。然而,在其他情况下,比如当两个写者或一个读者和一个写者希望在同一时间访问文件时,可能会出现一些问题,因此任务是以这样的方式设计代码:如果一个读者正在阅读,则不允许任何写者在同一时间更新;同样,如果一个写者正在写入,则不允许任何读者在该时间点读取文件;如果一个写者正在更新文件,则不应允许其他写者在同一时间更新文件。但是,多个读者可以同时访问对象。

让我们通过下表了解读写的可能性

表 1

情况方法 1方法 2允许/不允许
情况 1写作写作不允许
情况 2阅读写作不允许
情况 3写作阅读不允许
情况 4阅读阅读允许

读者和写者的解决方案可以使用二值信号量实现。

我们使用两个二值信号量“write”和“mutex”,其中二值信号量可以定义为

信号量:信号量是 S 中的一个整数变量,除了初始化之外,它只能通过两个标准原子操作——wait 和 signal 访问,其定义如下

从上述 wait 的定义可以清楚地看出,如果 S 的值 <= 0,它将进入无限循环(因为 while 循环后面的分号)。而 signal 的作用是增加 S 的值。

下面的代码将提供读者-写者问题的解决方案,读者和写者进程代码如下 -

读者进程的代码

读者进程的代码如下 -

在上述读者代码中,mutexwrite 是初始值为 1 的信号量,而 readcount 变量的初始值为 0。mutexwrite 在读者和写者进程代码中是通用的,信号量 mutex 确保互斥,信号量 write 处理写入机制。

readcount 变量表示同时访问文件的读者数量。当变量 readcount 变为 1 时,使用 wait 操作写入信号量,这将使值减 1。这意味着不允许写者再访问文件。完成读取操作后,readcount 减 1。当 readcount 变为 0 时,用于 write 的信号操作允许写者访问文件。

写者进程的代码

定义写者进程的代码如下

如果写者希望访问文件,则对 write 信号量执行 wait 操作,这会将 write 减到 0,并且没有其他写者可以访问文件。当访问文件的写者完成写入工作后,对 write 执行信号操作。

让我们看看表 1 中提到的每个案例的证明

案例 1:写入 - 写入 → 不允许。也就是说,当两个或两个以上进程希望写入时,是不允许的。让我们看看我们的代码是否按此工作?

案例 2:读取 - 写入 → 不允许。也就是说,当一个或一个以上进程正在读取文件时,不允许其他进程写入。让我们看看我们的代码是否按此工作?

案例 3:写入 -- 读取 → 不允许。也就是说,如果一个进程正在写入文件,则不允许其他进程读取。让我们看看我们的代码是否按此工作?

案例 4:读取 - 读取 → 允许。也就是说,当一个进程正在读取文件,而另一个或多个进程希望读取时,它们都被允许,即读取 - 读取不是互斥的。让我们看看我们的代码是否按此工作?


下一个主题戴尔操作系统