Semaphore solution to reader-writer: order between updating reader count and waiting or signaling on read/write binary semaphore?

橙三吉。 提交于 2019-12-04 05:55:01

问题


From Operating System Concepts

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

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

Figure 5.12 The structure of a reader process.

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

Thanks.


回答1:


  1. Why is wait/signal on rw_mutex guarded by semaphore mutex?

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

α 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 β.

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. In the structure of a reader process, Can I switch the order between updating read_count and wait/signal on rw_mutex, as following?

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".

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".


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 :Ь

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



来源:https://stackoverflow.com/questions/46881402/semaphore-solution-to-reader-writer-order-between-updating-reader-count-and-wai

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!