CMSC 421 Operating Systems Lecture Notes (c) 1997, Howard E. Motteler IPC Example: Readers and Writers ================================= Suppose we have shared data that a group of processes can both read and write Readers can share access with each other, but writers cannot share access with either readers or other writers One solution: a potential writer must wait for all readers to finish Problem: then writers can starve, if a succession of readers arrive Another solution: if a writer is waiting, then no other reader can gain access to the shared object. Problem: then readers can starve Starving writers ----------------- Suppose we have two semaphores, mutex and wrt, and a variable readcnt. Initially mutex and wrt are 1, and readcnt is 0 Readers: while (alive) { DOWN (mutex); readcnt = readcnt + 1; if (readcnt == 1) DOWN (wrt); UP (mutex); read shared data; DOWN (mutex) readcnt = readcnt - 1; if (readcnt == 0) UP (wrt); UP (mutex); } Writers: while (alive) { DOWN (wrt); write to shared data; UP (wrt); } Analysis: Multiple writers use wrt for mutual exclusion Suppose there is no active writer wrt readcnt initially 1 0 reader 1: readcnt++ 1 1 reader 1: DOWN(wrt) 0 1 (now any writer must wait) reader 2: readcnt++ 0 2 Note that the first reader has locked out the writers, and the second reader does not do a DOWN(wrt). Any number of readers can now keep the writers locked out, until the last reader does eventually: 0 1 reader k: readcnt-- 0 0 reader k: UP (wrt) 1 0 (writers can write again) If there is an active writer and some readers arrive, we have the case as follows 0 0 reader 1: readcnt++ 0 1 reader 1: DOWN(wrt) -1 1 The first reader waits from inside mutex, excluding subsequent readers A better solution ------------------ This is a simple, semi-fair readers and writers solution using a state variable and any form of mutual exclusion. States: Free: no active readers or writers AR: one or more readers are active AW: one writer is active S is single semaphore, used for mutual exclusion, and readcnt is the number of active readers Initially S = 1, readcnt = 0, state = Free, and k the desired time between tests of the state variable WRITER: while (alive) { wait(S); while (state == AR || state == AW) { signal(S); sleep(k); wait(S); } state = AW; /* signal(S); */ write_stuff(); /* wait(S); */ state = Free; signal(S); } READER: while (alive) { wait(S); while (state == AW) { signal(S); sleep(k); wait(S); } state = AR; readcnt++; signal(S); read_stuff(); wait(S); readcnt--; if (readcnt == 0) state = Free; signal(S); } Similarly to the TSL instruction, this solution does not guarantee bounded waiting for a fixed bound. Readers and writers contend on equal terms for access to a favorable state in their respective "while" loops