Ilmu Komputer    
   
Daftar Isi
(Sebelumnya) Reader LibraryReal Data Transport (Berikutnya)

Readers-writers problem

In computer science, the first and second readers-writers problems are examples of a common computing problem in concurrency. The two problems deal with situations in which many threads must access the same shared memory at one time, some reading and some writing, with the natural constraint that no process may access the share for reading or writing while another process is in the act of writing to it. (In particular, it is allowed for two or more readers to access the share at the same time.) A readers-writer lock is a data structure that solves one or more of the readers-writers problems.

Contents

The first readers-writers problem

Suppose we have a shared memory area with the constraints detailed above. It is possible to protect the shared data behind a mutual exclusion mutex, in which case no two threads can access the data at the same time. However, this solution is suboptimal, because it is possible that a reader R1 might have the lock, and then another reader R2 request access. It would be foolish for R2 to wait until R1 was done before starting its own read operation; instead, R2 should start right away. This is the motivation for the first readers-writers problem, in which the constraint is added that no reader shall be kept waiting if the share is currently opened for reading. This is also called readers-preference, with its solution below:

semaphore wrt=1,mutex=1;readcount=0;writer(){ wait(wrt); //writing is done signal(wrt);} reader(){ wait(mutex); readcount++; if(readcount==1) wait(wrt); signal(mutex); ///Do the Reading ///(Critical Section Area) wait(mutex); readcount--; if(readcount==0)   signal(wrt); signal(mutex);}

The second readers-writers problem

Suppose we have a shared memory area protected by a mutex, as above. This solution is suboptimal, because it is possible that a reader R1 might have the lock, a writer W be waiting for the lock, and then a reader R2 request access. It would be foolish for R2 to jump in immediately, ahead of W; if that happened often enough, W would starve. Instead, W should start as soon as possible. This is the motivation for the second readers-writers problem, in which the constraint is added that no writer, once added to the queue, shall be kept waiting longer than absolutely necessary. Here, P() is for wait and V() is for signal. This is also called writers-preference.

A solution to the writers-preference scenario is presented below:[1]

int readcount, writecount; (initial value = 0)semaphore mutex_1, mutex_2, mutex_3, w, r ; (initial value = 1) READER  P(mutex_3); P(r);  P(mutex_1); readcount := readcount + 1; if readcount = 1 then P(w);  V(mutex_1); V(r);  V(mutex_3);   reading is performed   P(mutex_1); readcount := readcount - 1; if readcount = 0 then V(w);  V(mutex_1); WRITER  P(mutex_2); writecount := writecount + 1; if writecount = 1 then P(r);  V(mutex_2);   P(w); writing is performed  V(w);   P(mutex_2); writecount := writecount - 1; if writecount = 0 then V(r);  V(mutex_2);

The third readers-writers problem

In fact, the solutions implied by both problem statements result in starvation — the first readers-writers problem may starve writers in the queue, and the second readers-writers problem may starve readers. Therefore, the third readers-writers problem is sometimes proposed, which adds the constraint that no thread shall be allowed to starve; that is, the operation of obtaining a lock on the shared data will always terminate in a bounded amount of time.

A solution with fairness for both readers and writers might be as follows:

 semaphores: no_waiting, no_accessing, counter_mutex ( initial value is 1 ) shared variables: nreaders ( initial value is 0 ) local variables:  prev, current WRITER: P( no_waiting ); P( no_accessing ); V( no_waiting );  ...  write ... V( no_accessing ); READER: P( no_waiting );  P( counter_mutex ); prev := nreaders; nreaders := nreaders + 1;  V( counter_mutex );  if prev = 0  then P( no_accessing ); V( no_waiting ); ... read ... P( counter_mutex );  nreaders := nreaders - 1;  current := nreaders; V( counter_mutex ); if current = 0 then V( no_accessing );

Note that sections protected by counter_mutex could be replaced by a suitable fetch-and-add atomic instruction, saving two potential context switches in reader's code.

Note also that this solution can only satisfy the condition that "no thread shall be allowed to starve" if and only if semaphores preserve first-in first-out ordering when blocking and releasing threads. Otherwise, a blocked writer, for example, may remain blocked indefinitely with a cycle of other writers decrementing the semaphore before it can.

References

  1. ^ Communications of the ACM :Concurrent Control with "Readers" and "Writers" P.J. Courtois,* F. H, 1971 [1]

See also

External links

(Sebelumnya) Reader LibraryReal Data Transport (Berikutnya)