cs444/cs544 operating systems
DESCRIPTION
CS444/CS544 Operating Systems. Classic Synchronization Problems 2/28/2007 Prof. Searleman [email protected]. Outline. Classic Synchronization Problems Dining Philosophers Deadlock, revisited Synchronization with Message Passing Events & Condition Variables NOTE: Read: Chapter 7 - PowerPoint PPT PresentationTRANSCRIPT
![Page 1: CS444/CS544 Operating Systems](https://reader035.vdocuments.site/reader035/viewer/2022062409/56814a43550346895db75ec0/html5/thumbnails/1.jpg)
CS444/CS544Operating Systems
Classic Synchronization Problems
2/28/2007
Prof. Searleman
![Page 2: CS444/CS544 Operating Systems](https://reader035.vdocuments.site/reader035/viewer/2022062409/56814a43550346895db75ec0/html5/thumbnails/2.jpg)
Outline Classic Synchronization Problems
Dining Philosophers Deadlock, revisited
Synchronization with Message Passing Events & Condition Variables
NOTE: Read: Chapter 7 Exam#2 – Tues. 3/13, 7:00 pm, SC160 K-12 TA interest meeting: 3/7, 4:00, Barben A
both undergrad & graduate TA’s available
![Page 3: CS444/CS544 Operating Systems](https://reader035.vdocuments.site/reader035/viewer/2022062409/56814a43550346895db75ec0/html5/thumbnails/3.jpg)
Classical Synchronization Problems
Bounded-Buffer Problem (also called Producer-Consumer)
one-way communication with limited resources
Dining-Philosophers Problem shared resources
Readers and Writers Problem shared database
![Page 4: CS444/CS544 Operating Systems](https://reader035.vdocuments.site/reader035/viewer/2022062409/56814a43550346895db75ec0/html5/thumbnails/4.jpg)
Dining-Philosophers Problem
#define N NUM_PHILOSOPHERS#define RIGHT i#define LEFT (i+1)%Nsemaphore_t chopstick[N];
void init(){ for (i=0; i<N; i++)
chopstick[i].value = 1;}
![Page 5: CS444/CS544 Operating Systems](https://reader035.vdocuments.site/reader035/viewer/2022062409/56814a43550346895db75ec0/html5/thumbnails/5.jpg)
Semaphore “Solution” to Dining Philosophers
void philosophersLife(int i){while (1) { think(); wait(chopstick[RIGHT]); grab_chopstick(RIGHT); wait(chopstick[LEFT]); grab_chopstick(LEFT); eat(); putdownChopsticks(); signal(chopstick[RIGHT]); signal(chopstick[LEFT]);}
}
Problem?
p0 gets chopstick 0 p1 gets chopstick 1 … pN-1 gets chopstick N-1
Deadlock potential! Solution?
![Page 6: CS444/CS544 Operating Systems](https://reader035.vdocuments.site/reader035/viewer/2022062409/56814a43550346895db75ec0/html5/thumbnails/6.jpg)
Deadlock
Deadlock exists in a set of processes/threads when all processes/threads in the set are waiting for an event that can only be caused by another process in the set (which is also waiting!).
Dining Philosophers is a perfect example. Each holds one chopstick and will wait forever for the other.
![Page 7: CS444/CS544 Operating Systems](https://reader035.vdocuments.site/reader035/viewer/2022062409/56814a43550346895db75ec0/html5/thumbnails/7.jpg)
Resource Allocation Graph
Deadlock can be described through a resource allocation graph
Each node in graph represents a process/thread or a resource
An edge from node P to R indicates that process P had requested resource R
An edge from node R to node P indicates that process P holds resource R
If graph has cycle, deadlock may exist. If graph has no cycle, deadlock cannot exist.
![Page 8: CS444/CS544 Operating Systems](https://reader035.vdocuments.site/reader035/viewer/2022062409/56814a43550346895db75ec0/html5/thumbnails/8.jpg)
Cycle in Resource Allocation Graph
wait(chopstick[i]);
wait(chopstick[(i+1)%N]);
Deadlock!Cycle: P0, C3, P3, C2, P2, C1, P1, C0, P0
Chopstick 2Philosopher 2 has chopstick 2 and wants chopstick 3
Philosopher 2
Philosopher 0 has chopstick 0 and wants chopstick 1
Philosopher 0
Chopstick 0 Chopstick 3
Philosopher 3 has chopstick 3 and wants chopstick 0
Philosopher 3
Interrupt &Context switch
P1 blocked
P3 blocked
P2 blocked
P0 blocked
Chopstick 1
Philosopher 1 has chopstick 1 and wants chopstick 2
Philosopher 1
![Page 9: CS444/CS544 Operating Systems](https://reader035.vdocuments.site/reader035/viewer/2022062409/56814a43550346895db75ec0/html5/thumbnails/9.jpg)
Fixing Dining Philosophers
Make philosophers grab both chopsticks they need atomically Maybe pass around a token (lock) saying who
can grab chopsticks Make a philosopher give up a chopstick Others?
![Page 10: CS444/CS544 Operating Systems](https://reader035.vdocuments.site/reader035/viewer/2022062409/56814a43550346895db75ec0/html5/thumbnails/10.jpg)
Better Semaphore Solution to Dining Philosophers void philosophersLife(int i){
while (1) { think(); if ( i < ((i-1) % NUM_PHILOSOPHERS))}{ wait(chopstick[i]); wait(chopstick[(i-1) % NUM_PHILOSOPHERS]); } else { wait(chopstick[(i-1) % NUM_PHILOSOPHERS]); wait(chopstick[i]); }
eat();
signal(chopstick[i]); signal(chopstick[(i-1) %
NUM_PHILOSOPHERS]);}
}
Why better?
philosopher 0 gets chopstick 0 philosopher 1 gets chopstick 1 …. philosopher N waits for chopstick 0
No circular wait! No deadlock!!
Always wait for low chopstick first
![Page 11: CS444/CS544 Operating Systems](https://reader035.vdocuments.site/reader035/viewer/2022062409/56814a43550346895db75ec0/html5/thumbnails/11.jpg)
No Cycle in Resource Allocation Graph
if ( i < ((i+1)%N))}{ wait(chopstick[i]); wait(chopstick[(i+1)%N]); } else { wait(chopstick[(i+1)%N]); wait(chopstick[i]); }
No cycle! No deadlock!Philosopher 0 will eat,then 3, then 2, then 1
Chopstick 2
Philosopher 2Philosopher 0
Chopstick 0
Chopstick 1
Philosopher 1
P0 blocked
Philosopher 3P3 blocked
P1 blocked
Chopstick 3
P2 can still run,request & get chopstick 3,eat,release chopsticks 2 & 3
![Page 12: CS444/CS544 Operating Systems](https://reader035.vdocuments.site/reader035/viewer/2022062409/56814a43550346895db75ec0/html5/thumbnails/12.jpg)
Recall: Conditions for Deadlock
Deadlock can exist if and only if the following four conditions are met; Mutual Exclusion – some resource must be held exclusively Hold and Wait – some process must be holding one resource
and waiting for another No preemption – resources cannot be preempted Circular wait – there must exist a set of processes (p1,p2, …
pn) such that p1 is waiting for p2, p2 is waiting for p3, … pn is waiting for p1
All these held in the Dining Philosopher’s first “solution” we proposed
Can’t really do anything about preventing mutual exclusion; so what are the other options?
![Page 13: CS444/CS544 Operating Systems](https://reader035.vdocuments.site/reader035/viewer/2022062409/56814a43550346895db75ec0/html5/thumbnails/13.jpg)
Preventing Hold and Wait(partial allocation)
Do not allow processes to hold a resource when requesting others Make philosophers get both chopsticks at once Window’s WaitForMultipleObjects
Make processes ask for all resources they need at the beginning Disadvantage: May not need all resources the whole time Can release them early but must hold until used
Make processes release any held resources before requesting more Hard to program!
![Page 14: CS444/CS544 Operating Systems](https://reader035.vdocuments.site/reader035/viewer/2022062409/56814a43550346895db75ec0/html5/thumbnails/14.jpg)
Preventing No Preemption
Preemption (have to love those double negative ) Allow system to take back resources once granted
Make some philosopher give back a chopstick
Disadvantage: Hard to program System figures out how to take away CPU and memory
without breaking programmer’s illusion How do you take away access to an open file or a lock
once granted?? Would need API to notify program and then code to deal with the removal of the resource at arbitrary points in the code Checkpoint and Rollback?
![Page 15: CS444/CS544 Operating Systems](https://reader035.vdocuments.site/reader035/viewer/2022062409/56814a43550346895db75ec0/html5/thumbnails/15.jpg)
Preventing Circular wait
Impose an ordering on the possible resources and require that processes request them in a specific order
How did we prevent deadlock in dining philosophers? Numbered the chopsticks Made philosophers ask for lowest number chopstick first
Disadvantage: Hard to think of all types of resources in system and number
them consistently for all cooperating processes I use a resource X and Y , you use resource Y and Z and W,
someone else uses W, T, R – which is resource 1? (shared files, databases, chopsticks, locks, events, …)
For threads in the same process or closely related processes often isn’t that bad
![Page 16: CS444/CS544 Operating Systems](https://reader035.vdocuments.site/reader035/viewer/2022062409/56814a43550346895db75ec0/html5/thumbnails/16.jpg)
Deadlock Avoidance
Avoidance vs Prevention? Both actually prevent deadlock Deadlock Prevention does so by breaking one of the four
necessary conditions Deadlock Avoidance allows processes to make any request they
want (not constrained in ways so as to break one of the four conditions) *as long as* they declare their maximum possible resource requests at the outset
Deadlock avoidance usually results in higher resource allocation by allowing more combinations of resource requests to proceed than deadlock prevention
Still deadlock avoidance can deny resource requests that would not actually lead to deadlock in practice
More on this later...
![Page 17: CS444/CS544 Operating Systems](https://reader035.vdocuments.site/reader035/viewer/2022062409/56814a43550346895db75ec0/html5/thumbnails/17.jpg)
Dining Philosophers Monitor
monitor DP { /* diningPhilosophers */ enum Moods{thinking, hungry, eating};
Moods state[N]; /* N is Num_Philosophers */ condition self[N];
void pickup(int i); void putdown(int i) ; void test(int i) ; void init() { for (int i=0; i < N; i++) state[i] = thinking; }}
![Page 18: CS444/CS544 Operating Systems](https://reader035.vdocuments.site/reader035/viewer/2022062409/56814a43550346895db75ec0/html5/thumbnails/18.jpg)
Dining Philosophers Monitor/********************************************** * Consider philosopher i (pi):
* state[i] is * thinking (don’t need resources), * hungry (want resources), * eating (have all needed resources) * self[i] is a condition variable for pi
* used when i has to wait for resources * state[(i+N-1) % N] is * the state of the philosopher to pi’s right
* state[(i+1) % N] is * the state of the philosopher to pi’s left
*********************************************/
![Page 19: CS444/CS544 Operating Systems](https://reader035.vdocuments.site/reader035/viewer/2022062409/56814a43550346895db75ec0/html5/thumbnails/19.jpg)
Dining Philosophers Monitor
void pickupChopsticks(int i) {state[i] = hungry;test[i];if (state[i] != eating)
self[i].wait();}
void putdownChopsticks(int i) {state[i] = thinking;// test left and right neighborstest((i+(N-1)) % N);test((i+1) % N);
}
![Page 20: CS444/CS544 Operating Systems](https://reader035.vdocuments.site/reader035/viewer/2022062409/56814a43550346895db75ec0/html5/thumbnails/20.jpg)
Dining Philosophers Monitor
void test(int i) { if ((state[(i+N-1) % N] != eating) && (state[i] == hungry) && (state[(i+1) % N] != eating)) { state[i] = eating; self[i].signal();
}}
} /* end DP monitor */
![Page 21: CS444/CS544 Operating Systems](https://reader035.vdocuments.site/reader035/viewer/2022062409/56814a43550346895db75ec0/html5/thumbnails/21.jpg)
Dining Philosophers
Each “philosopher” thread executes:
void philosophersLife(int i) {while(1){
think();DP.pickupChopsticks();eat();DP.putdownChopsticks();
}}
![Page 22: CS444/CS544 Operating Systems](https://reader035.vdocuments.site/reader035/viewer/2022062409/56814a43550346895db75ec0/html5/thumbnails/22.jpg)
Generalize to Messaging
Synchronization based on data transfer (atomic) across a channel
In general, messages can be used to express ordering/scheduling constraints Wait for message before do X Send message = signal
Direct extension to distributed systems
![Page 23: CS444/CS544 Operating Systems](https://reader035.vdocuments.site/reader035/viewer/2022062409/56814a43550346895db75ec0/html5/thumbnails/23.jpg)
Window’s Events & UNIX Signals
Window’s Events Synchronization objects used somewhat like semaphores
when they are used for ordering/scheduling constraints One process/thread can wait for an event to be signaled by
another process/thread Recall: UNIX signals
Kill = send signal; Signal = catch signal Many system defined but also signals left to user definition Can be used for synchronization
Signal handler sets a flag Main thread polls on the value of the flag Busy wait though
![Page 24: CS444/CS544 Operating Systems](https://reader035.vdocuments.site/reader035/viewer/2022062409/56814a43550346895db75ec0/html5/thumbnails/24.jpg)
Window’s Events Create/destroyHANDLE CreateEvent(
LPSECURITY_ATTRIBUTES lpsa, // security privileges (default = NULL) BOOL bManualReset, // TRUE if event must be reset manually BOOL bInitialState, // TRUE to create event in signaled state LPTSTR lpszEventName ); // name of event (may be NULL)
BOOL CloseHandle( hObject );
WaitDWORD WaitForSingleObject(
HANDLE hObject, // object to wait for
DWORD dwMilliseconds );
Signal (all threads that wait on it receive)BOOL SetEvent( HANDLE hEvent ); //signal onBOOL ResetEvent( HANDLE hEvent ); //signal off
![Page 25: CS444/CS544 Operating Systems](https://reader035.vdocuments.site/reader035/viewer/2022062409/56814a43550346895db75ec0/html5/thumbnails/25.jpg)
Pthread’s Condition Variables Create/destroyint pthread_cond_init (pthread_cond_t *cond,
pthread_condattr_t *attr); int pthread_cond_destroy (pthread_cond_t *cond);
Waitint pthread_cond_wait (pthread_cond_t *cond,
pthread_mutex_t *mut);
Timed Waitint pthread_cond_timedwait (pthread_cond_t *cond,
pthread_mutex_t *mut, const struct timespec *abstime);
Signal
int pthread_cond_signal (pthread_cond_t *cond); Broadcast
int pthread_cond_broadcast (pthread_cond_t *cond);