问题
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
andrw_mutex
are initialized to 1; read count is initialized to 0. The semaphorerw_mutex
is common to both reader and writer processes. Themutex
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 semaphorerw_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.
- Why is
wait
/signal
onrw_mutex
guarded by semaphoremutex
? In the structure of a reader process, Can I switch the order between updaing
read_count
andwait
/signal
onrw_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:
- Why is
wait
/signal
onrw_mutex
guarded by semaphoremutex
?
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.
- In the structure of a reader process, Can I switch the order between updating
read_count
andwait
/signal
onrw_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