Download presentation
Presentation is loading. Please wait.
Published byJeffry Neal Modified over 9 years ago
1
Classic problems of Synchronization : Producers/Consumers problem: The producers/ consumers problem may be stated as follows: Given a set of cooperating processes, some of which “produce” data items(producers) to be “consumed” by others(consumers), with possible disparity between production and consumption rates, Devise a synchronization protocol that allows both producers and consumers to operate concurrently at their respective service rates in such a way that produced items are consumed in the exact order in which they are produced(FIFO)
2
Solution to producers/ consumers problem : unbounded buffer program producer-consumer; … var produced: semaphore; {general} process producer; begin while true do begin produce; place_in_buffer; signal(produced); other_producer_processing end{while} end; {producer}
3
process consumer; begin while true do begin wait(produced); take_from_buffer; consume; other_consumer_processing end{while} end; {consumer} {parent process} begin{producer-consumer} produced = 0; initiate producer, consumer end {producer-consumer}
4
Solution to Bounded buffer Producers_Consumers Problem using Semaphores program BB_producers_consumers const capacity = …; type item = …; var buffer: array[1..capacity] of item; empty, full : semaphore; {general} pmutex, cmutex :semaphore; {binary} in, out :(1..capacity);
5
process producerX; var pitem : item; begin while true do begin wait(empty); pitem = produce; wait(pmutex); buffer[in] = pitem; in = (in + 1) mod capacity; signal(pmutex); signal(full); other_X_processing end {while} end; {producerX}
6
process consumerZ; var citem : item; begin while true do begin wait(full); wait(cmutex); citem = buffer[out]; out = (out mod capacity) + 1; signal(cmutex); signal(empty); other_Z_processing end {while} end; {consumerZ}
7
{parent process} begin {BB_producers_consumers} in := 1; out := 1; signal(pmutex); signal(cmutex); full := 0; for i:= 1 to capacity do signal(empty); initiate producers, consumers end { BB_producers_consumers }
8
Readers Wriiters Problem The Readers/Writers problem may be stated as follows: Given a universe of readers that read a common data structure, and a universe of writers that modify the same common data structure, Devise a synchronization protocol among the readers and writers that ensures consistency of common data while maintaining as high a degree of concurrency as possible. Variants of Readers-Writers Favor readers No reader waits unless a writer is already in critical section. A reader that arrives after a waiting writer gets priority over writer. Favor writers Once a writer is ready to write, it performs its write as soon as possible. A reader that arrives after a writer must wait, even if the writer is also waiting Starvation (thread waits indefinitely) possible in both cases.
9
Solution to Readers Writers Problem using Semaphores program readers_writers; var readercount : integer; mutex, write : semaphore; {binary} process readerX; begin while true do begin {obtain permission to enter} wait(mutex); readercount := readercount +1; if readercount = 1 then wait(write); signal(mutex); ….. {reads} … wait(mutex); readercount = readercount – 1; if readercount = 0 then signal(write); signal(mutex); other_X_processing end {while} end; {reader}
10
process writerZ; begin while true do begin wait(write); … signal(write); Other_Z_processing end {while} end; {writerZ} {parent process} begin {readers_writers} readercount : = 0; signal(mutex); signal (write); initiate readers, writers end {readers_writers}
11
The Dining Philosophers’ Problem The Dining Philosophers problem is a classic OS problem that’s usually stated in very non-OS terms: There are N philosophers sitting around a circular table eating spaghetti and discussing philosophy. The problem is that each philosopher needs 2 forks to eat, and there are only N forks, one between each 2 philosophers. Design an algorithm that the philosophers can follow that ensures that none starves as long as each philosopher eventually stops eating, and such that the maximum number of philosophers can eat at once. Here’s an approach to the Dining Philosphers that’s simple and wrong: void philosopher() { while(1) { sleep(); get_left_fork(); get_right_fork(); eat(); put_left_fork(); put_right_fork(); } If every philosopher picks up the left fork at the same time, no one gets to eat - ever.
12
Some other suboptimal alternatives: Pick up the left fork, if the right fork isn’t available for a given time, put the left fork down, wait and try again. (Big problem if all philosophers wait the same time - we get the same failuremode as before, but repeated.) Even if each philosopher waits a different random time, anunlucky philosopher may starve (in the literal or technical sense). Require all philosophers to acquire a binary semaphore before picking up any forks. This guarantees that no philosopher starves (assuming that the semaphore is fair) but limits parallelism dramatically.
13
#define N 5 /* Number of philosphers */ #define RIGHT(i) (((i)+1) %N) #define LEFT(i) (((i)==0) ? N-1 : (i)+1) typedef enum { THINKING, HUNGRY, EATING } phil_state; phil_state state[N]; semaphore mutex =1; semaphore s[N]; /* one per philosopher, all 0 */ void get_forks(int i) { state[i] = HUNGRY; while ( state[i] == HUNGRY ) { wait(mutex); if ( state[i] == HUNGRY && state[LEFT(i)] != EATING && state[RIGHT(i)] != EATING ) { state[i] = EATING; signal(s[i]); } signal(mutex); wait(s[i]); }
14
void put_forks(int i) { wait(mutex); state[i]= THINKING; if ( state[LEFT(i)] == HUNGRY ) signal(s[LEFT(i)]); if ( state[RIGHT(i)] == HUNGRY) signal(s[RIGHT(i)]); signal(mutex); } void philosopher(int process) { while(1) { think(); get_forks(process); eat(); put_forks(); }
15
monitorname : monitor; begin declarations of private data ; {local monitor variables}... procedure pubname(formal parameters); {public procedures} begin procedure_body; end;... procedure privname {private procedures}... initialization of monitor data;... end monitorname;
16
Producers/Consumers monitor : Bounded buffer module m_producers_consumers... b_b : monitor; begin buffer : array [ 1.. capacity] of item; int count; in, out : (0..capacity); mayproduce, mayconsume : condition;
17
procedure mput(pitem :item) : { public} begin if count ==capacity then mayproduce.wait; buffer[in] = pitem; in : = (in mod capavity) + 1; count : = count +1; mayconsume.signal end; {mput}
18
procedure mtake( var citem :item) : { public} begin if count == 0 then mayconsume.wait; citem = buffer[out]; out : = (out mod capavity) + 1; count : = count - 1; mayproduce.signal; end; {mtake}
19
{monitor body – initialization} in: = 1; out : = 1; count: = 0; end b_b; end {m_producers_consumers}
20
module producers_consumers;... process producerX; var pitem: item; begin while true do begin pitem : = produce; b_b.mput(pitem); other_X_processing end {while} end; {producerX}...
21
process consumerZ; var citem : item; begin while true do begin b_b.mtake(citem); consume(citem); other_Z_processing end {while} end; {consumeZ}
22
{parent process} begin initiate producers_consumers end {users} end {producers_consumers}
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.