问题
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
mutexandrw_mutexare initialized to 1; read count is initialized to 0. The semaphorerw_mutexis common to both reader and writer processes. Themutexsemaphore 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_mutexfunctions 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/signalonrw_mutexguarded by semaphoremutex? In the structure of a reader process, Can I switch the order between updaing
read_countandwait/signalonrw_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/signalonrw_mutexguarded 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_countandwait/signalonrw_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