Upload
oscar-king
View
217
Download
0
Embed Size (px)
Citation preview
Critical Problem Revisit
Critical Sections
• Mutual exclusion Only one process can be in the critical section at a timeWithout mutual exclusion, results of multiple execution are not consistent
• There is a race to execute critical sections
• The sections may be defined by different code in different processes. Need an OS mechanism so programmer can resolve races
Some Possible OS Mechanisms
Disable interrupts, Synchronization hardware Software solution – locks, semaphores, monitors
Disabling Interruptsshared double balance;
Code for pi Code for pj
disableInterrupts(); disableInterrupts(); balance = balance + amount; balance = balance - amount;enableInterrupts(); enableInterrupts();
Disadvantages A user process can easily abuse this privilege and hence should not be available to
a user process.
Interrupts could be disabled arbitrarily long
We only want to prevent pi and pj from interfering with one another; this prevents any other process pk to execute
In a Multiprocessor system, disabling interrupts in one processor will not disable it in another process and hence mutual exclusion is not guaranteed
Disabling interrupts guarantees mutual exclusion, but …
Hardware Synchronization
TestAndSet()Swap()
How to use Hardware Synchronization to achieve mutual exclusion and bounded waiting
Lock
shared boolean lock = FALSE;
Code for pi Code for pj
. . . . . .acquire(lock); acquire(lock);
<execute critical section>; <execute critical section>; release(lock); release(lock); . . . . . .
However, acquire(lock) and release(lock) operations must be atomic !
Important considerations for software locks
Mutual exclusion: Only one process at a time in the Critical Section (CS)
A process should not be delayed access to a critical section when there is no other process using it
Once a process attempts to enter its CS, it should not be postponed indefinitely NO STARVATION! (After requesting entry, only a bounded number of other processes may enter before the requesting process)
Semaphore
• A semaphore, s, is a integer variable that can only be changed or tested by these two atomic (indivisible / uninterruptable) functions:
P(s) (wait(s))V(s) (signal(s))
Semaphore solutionstruct semaphore {
int value;process *queue;
}
P(semaphore s): disable_interrupts();{ s.value--;
if (s.value < 0){place this process in s.queue; block this process}
enable_interrupts();}
V(semaphore s):{disable_interrupts(); s.value++;
if (s.value <= 0){ remove a process P from s.queue; wakeup P;}
enable_interrupts();}
get( ) P( ) wait( ) pthread_mutex_lock()
release( ) V( ) signal( ) pthread_mutex_unlock()
Shared Account Problem
Pi(){
. . ./* Enter the CS */ P(mutex); balance += amount; V(mutex);
. . .}
semaphore mutex = 1;
pthread_create(P0, 0);pthread_create(P1, 0);
Pj(){
. . ./* Enter the CS */ P(mutex); balance -= amount; V(mutex);
. . .}
shared lock1 = FALSE;shared lock2 = FALSE;
Code for p2
. . .
/* Enter CS-2*/ P(lock2); <critical section 2>; V(lock2);
<other computation>;
/* Enter CS-1 */ P(lock1); <critical section 1>; V(lock1);
. . .
Processing Two Critical Sections
shared lock1 = FALSE;shared lock2 = FALSE;
Code for p1
. . .
/* Enter CS-1 */ P(lock1); <critical section 1>; V(lock1);
<other computation>;
/* Enter CS-2 */ P(lock2); <critical section 2>; V(lock2);
. . .
Deadlock may occur if locks are not used properly!
shared boolean lock1 = FALSE;shared boolean lock2 = FALSE;
Code for p1 Code for p2
. . . . . . P(lock1); P(lock2);
<delete element>; <update length>;
/* Enter CS to update length */ /* Enter CS to add element */
P(lock2); P(lock1); <update length>; <add element>;
V(lock2); Vlock1);
V(lock1); V(lock2); . . . . . .
Classical Problems of Synchronization
Classical Problems of Synchronization
• Bounded-Buffer Producer/Consumer Problem• Readers and Writers Problem• Dining Philosophers Problem
Bounded-Buffer Producer/Consumer Problem
• Shared data: semaphore full, empty, mutex
• Initially: full = 0, empty = n, mutex = 1 where n is the buffer size
do { …
produce an item …
P(empty);P(mutex);
…add the item to the buffer
…V(mutex);
V(full);
} while (TRUE);
The producer must wait for an empty space in the buffer
We must make sure that the producer and the consumer make changes to the shared buffer in a mutually exclusive manner
Bounded-Buffer Producer/Consumer Problem
do { P(full)P(mutex);
…remove an item from the buffer
…V(mutex);V(empty);
…consume the item
…} while (TRUE);
We must make sure that the producer and the consumer make changes to the shared buffer in a mutually exclusive manner
The consumer must wait for a filled space in the buffer
Bounded-Buffer Producer/Consumer Problem
• Motivation: Consider a shared database– Two classes of users:
• Readers – never modify database
• Writers – read and modify database
– Is using a single lock on the whole database sufficient?• Like to have many readers at the same time
• Only one writer at a time
RR
R
W
Readers/Writers Problem
Readers/Writers Problem• A database is to be shared among several concurrent processes. Some of
these processes may want only to read the database, whereas others may want to update the database
• We distinguish between these two types of processes by referring to the former as readers and to the latter as writers
• Obviously, if two readers access the shared data simultaneously, nothing bad will happen
• However, if a writer and some other process (either a reader or a writer) access the database simultaneously, chaos may ensue
Readers/Writers Problem• To ensure that these difficulties do not arise, we require that the writers
have exclusive access to the shared database
• This synchronization problem has been used to test nearly every new synchronization primitive
• There are several variations of this problem, all involving priorities
– The first and simplest one, referred to as the first readers/writers problem, requires that no reader will be kept waiting unless a writer has already obtained permission to use the shared object (i.e., no reader should wait for other readers to finish simply because a writer is waiting) NOTE: writers may starve
– The second readers/writers problem requires that, once a writer is ready, that writer performs its write as soon as possible (i.e., if a writer is waiting, no new readers may start reading) NOTE: readers may starve
First Readers/Writers Problem
• Shared data: semaphore mutex, wrt int readcount
• Initially: mutex = 1, wrt = 1, readcount =0
do {P(wrt);
…writing is performed
…V(wrt);
} while (TRUE);
A writer will wait if either another writer is currently writing or one or more readers are currently reading
First Readers/Writers Problem
First Readers/Writers Problemdo{
P(mutex);readcount++;if (readcount == 1) P(wrt);V(mutex); …reading is performed
…P(mutex);readcount--;if (readcount == 0) V(wrt);
V(mutex);
} while(TRUE);
We must make sure that readers update the shared variable readcount in a mutually exclusive manner
A reader will wait only if a writer is currently writing. Note that if readcount == 1, no reader is currently reading and thus that is the only time that a reader has to make sure that no writer is currently writing (i.e., if readcount > 1, there is at least one reader reading and thus the new reader does not have to wait)
First Reader/Writer SolutionReader:do{
P(mutex);readcount++;if (readcount == 1) P(wrt);V(mutex); …reading is performed
…P(mutex);readcount--;if (readcount == 0) V(wrt);
V(mutex);
} while(TRUE);
Writer:
do {P(wrt);
…writing is performed
…V(wrt);
} while (TRUE);
• First reader competes with writers • Last reader signals writers• Any writer must wait for all readers• Readers can starve writers• “Updates” can be delayed forever not desirable!
reader() { while(TRUE) { <other computing>;
P(RD); P(mutex1); readCount++; if(readCount == 1) P(WRT); V(mutex1); V(RD);
access(resource); P(mutex1); readCount--; if(readCount == 0) V(WRT); V(mutex1); }}
int readCount=0, writeCount=0;semaphore mutex1=1, mutex2=1;semaphore RD=1,WRT=1
writer() { while(TRUE) { <other computing>; P(mutex2); writeCount++; if(writeCount == 1) P(RD); V(mutex2); P(WRT); access(resource); V(WRT); P(mutex2) writeCount--; if(writeCount == 0) V(RD); V(mutex2); }}
• Writers can starve readers• “Reads” can be delayed forever Not desirable, either !
Favor Writer
Dining Philosophers Problem
• Five philosophers spend their lives thinking and eating• When a philosopher gets hungry, he/she tries to pick up the
two chopsticks that are closest to him or her. He/she may pick up only one chopstick at a time. When finished eating, he/she puts down both chopsticks and starts thinking
• A classic synchronization problem. It is an example of a large class of concurrency-control problems. It is a simple representation of the need to allocate several resources among several processes in a deadlock-free and starvation-free manner
Dining Philosophers Problem
• Shared data semaphore chopstick[5]
Initially all values are 1
Dining Philosophers Problem – Philosopher i
do {P(chopstick[i])P(chopstick[(i+1) % 5])
…eat …
V(chopstick[i]);V(chopstick[(i+1) % 5]);
…think …
} while (TRUE);
A philosopher must wait for his/her left and right chopsticks to be available before he/she can start eating
Dining Philosophers Problem
• This solution guarantees that no two neighbors can be eating simultaneously (i.e., mutual exclusion)
• Do you see any problem(s) with this solution?– This solution could create a deadlock. How?