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

问题描述:

根据操作系统概念

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

In the solution to the first readers–writers problem, the reader processes share the following data structures:

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编写器进程的结构.

Figure 5.11 The structure of a writer process.

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阅读器进程的结构.

Figure 5.12 The structure of a reader process.

信号量mutexrw_mutex初始化为1;读取计数 初始化为0.信号量rw_mutex是两个共同的 读者和作家的过程. mutex信号量用于确保 变量读取计数更新时的互斥.阅读 计数变量跟踪当前正在读取多少个进程 物体.信号量rw_mutex用作互斥 作家的信号灯.第一个或最后一个读者也使用它 进入或退出关键部分的代码.读者不使用 谁进入或退出而其他读者仍在他们的关键区域.

The semaphores mutex and rw_mutex are initialized to 1; read count is initialized to 0. The semaphore rw_mutex is common to both reader and writer processes. The mutex semaphore is used to ensure mutual exclusion when the variable read count is updated. The read count variable keeps track of how many processes are currently reading the object. The semaphore rw_mutex functions as a mutual exclusion semaphore for the writers. It is also used by the first or last reader that enters or exits the critical section. It is not used by readers who enter or exit while other readers are in their critical sections.

  1. 为什么rw_mutex上的wait/signal受信号量mutex保护?
  2. 在阅读器进程的结构中,我可以在以下之间切换顺序吗? 将rw_mutex上的read_countwait/signal更新为 正在关注吗?

  1. Why is wait/signal on rw_mutex guarded by semaphore mutex?
  2. In the structure of a reader process, Can I switch the order between updaing read_count and wait/signal on rw_mutex, as following?

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);

谢谢.

  1. 为什么rw_mutex上的wait/signal受信号量mutex保护?
  1. Why is wait/signal on rw_mutex guarded by semaphore mutex?

想象一下不是,也就是说,只有read_count行受到保护,并且您具有读取器线程α和β.

Imagine it's not, i.e. only read_count lines are guarded, and that you have reader threads α and β.

α增加read_count,执行signal(mutex),然后执行if (read_count == 1),并且-h! — CPU调度程序决定足够了,让其他线程也玩得开心!" ,然后开始执行线程β.

α increases read_count, executes signal(mutex), and goes to executing if (read_count == 1), and — bah! — CPU scheduler decides "enough, let other threads to have a fun too!", and starts executing thread β.

线程β锁定mutex,增大read_count,释放mutex,并且也开始执行if (read_count == 1).现在,由于read_count为2,两个线程中的比较都失败了,因此没有读取器采用rw_mutex,而您的写入器将写入正在读取的数据.

Thread β locks mutex, increases read_count, releases mutex, and also starts executing if (read_count == 1). Now, because read_count is 2, comparisons in both threads fails, so none of readers take the rw_mutex, and your writer goes writing over the data being read.

  1. 在读取器进程的结构中,是否可以按以下方式在更新read_countwait/signal之间进行切换?
  1. In the structure of a reader process, Can I switch the order between updating read_count and wait/signal on rw_mutex, as following?

是的,可以.区别纯粹是语义上的:原始读物为我们将要阅读,因此增加read_count,如果我们是唯一的阅读器,则锁定rw_mutex.执行阅读.完成后,减少read_count,如果我们是最后一个读者,则解锁rw_mutex".

Yes, you can. The distinction is purely semantical: the original reads as "We're about to read, so increase read_count, and if we're the only reader, lock rw_mutex. Perform reading. Then, as we're done, decrease read_count, and if we were the last reader, unlock rw_mutex".

您的变体读为"如果没有人读,则锁定rw_mutex.然后增加read_count.执行阅读.然后,如果我们是唯一的读者,则解锁rw_mutex.减小read_count"" .

Your variant reads as "if nobody reads, lock rw_mutex. Then increase read_count. Perform reading. Then, if we were the only reader, unlock rw_mutex. Decrease read_count".

但是,如果作者使用了您的变体,可能会略有兴趣,我对第一个问题的回答会更长一些,因为另外,在signal(rw_mutex)的代码部分中,您可以陷入僵局:Ь

It might out of slight interest though, that if the author have used your variant, my answer to the first question would've been a bit longer because additionally, in the part of code with signal(rw_mutex), you could've get a deadlock :Ь

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

Also, the concept author is describing in C++ is the std::shared_mutex.