Last time ❒ Need for synchronization primitives 7: Synchronization ❒ Locks and building locks from HW primitives ❒ Semaphores and building semaphores from Last Modified: locks 10/8/2002 9:37:06 PM -1 -2 Uses of Semaphores Semaphores for expressing ordering ❒ Mutual exclusion ❒ Initialize semaphore value to 0 ❍ Binary semaphores (wait/signal used just like ❒ Code: lock/unlock) P i P j ❍ “hold” ❒ Managing N copies of a resource M M ❍ Counting semaphores A wait ❍ “enter” signal B ❒ Anything else? ❒ Execute B in P j only after A executed in P i ❍ Another type of synchronization is to express ❒ Note: If signal executes first, wait will ordering/scheduling constraints find it is an signaled state (history!) ❍ “Don’t allow x to proceed until after y” -3 -4 Window’s Events and UNIX Window’s Events Signals ❒ Window’s Events � Create/destroy ❍ Synchronization objects used somewhat like semaphores HANDLE CreateEvent( when they are used for ordering/scheduling constraints LPSECURITY_ATTRIBUTES lpsa, // security privileges (default = NULL) BOOL bManualReset, // TRUE if event must be reset manually ❍ One process/thread can wait for an event to be signaled BOOL bInitialState, // TRUE to create event in signaled state by another process/thread LPTSTR lpszEventName ); // name of event (may be NULL) ❒ Recall: UNIX signals BOOL CloseHandle( hObject ); ❍ Kill = send signal; Signal = catch signal � Wait ❍ Many system defined but also signals left to user DWORD WaitForSingleObject( definition HANDLE hObject, // object to wait for ❍ Can be used for synchronization DWORD dwMilliseconds ); � Signal (all threads that wait on it receive) • Signal handler sets a flag • Main thread polls on the value of the flag BOOL SetEvent( HANDLE hEvent ); //signal on • Busy wait though BOOL ResetEvent( HANDLE hEvent ); //signal off -5 -6
Generalize to Messaging Problems with Semaphores ❒ Synchronization based on data transfer ❒ There is no syntactic connection between the (atomic) across a channel semaphore ( or lock or event) and the shared ❒ In general, messages can be used to data/resources it is protecting express ordering/scheduling constraints ❍ Thus the “meaning” of the semaphore is defined by the programmer’s use of it ❍ Wait for message before do X • Bad software engineering ❍ Send message = signal – Semaphores basically global variables accessed by all threads ❒ Direct extension to distributed systems • Easy for programmers to make mistakes ❒ Also no separation between use for mutual exclusion and use for resource management and use for expressing ordering/scheduling constraints -7 -8 Programming Language Support Monitors ❒ Add programming language support for ❒ A monitor is a software module that synchronization encapsulates: ❍ Declare a section of code to require mutually ❍ Shared data structures exclusive access (like Java’s synchronized) ❍ Procedures that operated on them ❍ Associate the shared data itself with the ❍ Synchronization required of processes that locking automatically invoke these procedures ❒ Monitor = programming language support to ❒ Like a public/private data interface enforce synchronization prevents access to private data members; ❍ Mutual exclusion code added by the compiler! Monitors prevent unsynchronized access to shared data structures -9 -10 Example: bankAccount Monitor Monitor bankAccount{ int balance; balance Shared data int readBalance( ){return balance}; One thread void upateBalance(int newBalance){ In Monitor Locking added balance = newBalance; readBalance S by the compiler! } int withdraw (int amount) { updateBalance Procedures Waiting queue withdraw balance = balance – amount; return balance; deposit } int deposit (int amount){ balance = balance + amount; return balance; } } -11 -12
Waiting Inside a Monitors Wait and signal ❒ Condition variables, like semaphores, have ❒ What if you need to wait for an event within one the two operations have the two of the procedures of a monitor? operations, wait and signal. ❒ Monitors as we have seen to this point enforce mutual exclusion – what about the ❍ The operation x.wait() means that the process invoking this operation is suspended until ❒ Introduce another synchronization object, the another process invokes x.signal(); condition variable ❍ The operation wait allows another process to ❒ Within the monitor declare a condition variable: enter the monitor (or no one could ever call condition x; signal!) ❍ The x.signal operation resumes exactly one suspended process. If no process is suspended, then the signal operation has no effect -13 -14 Semaphores vs Condition Monitor With Condition Variables Variables Condition Variables and their associated wait queues ❒ I’d like to be able to say that condition variables are just like semaphores but … balance One thread ❒ With condition variables, if no process is Running in suspended then the signal operation has no Monitor readBalance effect S updateBalance ❒ With semaphores, signal increments the Waiting queue withdraw value regardless of whether any process is deposit waiting ❒ Semaphores have “history” (they remember signals) while condition variables have no history -15 -16 Condition Variables for Condition Variable Alone? ordering/scheduling ❒ Could you use a condition variable concept outside of monitors? ❒ Code: ❒ Yes, basically a semaphore without history P i P j ❍ Couldn’t do locking with it because no mutual M M exclusion on its own A wait ❍ Couldn’t do resource management (counting signal B semaphore) because no value/history ❍ Could you use it for ordering/scheduling ❒ Execute B in P j only after A executed in P i constraints? Yes but with different semantics ❒ If signal first, it is lost; wait will block until next signal ( no history!) -17 -18
Pseudo-Monitors Pthread’s Condition Variables ❒ Monitor = a lock (implied/added by � Create/destroy compiler) for mutual exclusion PLUS zero int pthread_cond_init (pthread_cond_t *cond, pthread_condattr_t *attr); int pthread_cond_destroy (pthread_cond_t *cond); or more condition variables to express � Wait ordering constraints int pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mut); � Timed Wait ❒ What if we wanted to have monitor without programming language support? int pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mut, const struct timespec *abstime); ❍ Declare locks and then associate condition � Signal variables with a lock int pthread_cond_signal (pthread_cond_t *cond); ❍ If wait on the condition variable, then release � Broadcast the lock int pthread_cond_broadcast (pthread_cond_t *cond); -19 -20 Example: Pseudo-monitors More about monitors pthread_mutex_t monitorLock; pthread_cond_t conditionVar; void pseudoMonitorProc(void) { pthread_mutex_lock(&mutexLock); ….. pthread_cond_wait(&conditionVar, &monitorLock); …. pthread_mutex_unlock(&mutexLock); } -21 -22 Monitor Invariants Who first? ❒ Can specify invariants that should hold ❒ If thread in Monitor calls x.signal waking whenever no thread is in the monitor another thread then who is running in the monitor now? (Can’t both be running in the ❒ Not checked by compiler monitor!) ❒ More like a precondition to be respected ❒ Hoare monitors by the programmer ❍ Run awakened thread next; signaler blocks ❒ Mesa monitors ❍ Waiter is made ready; signaler continues -23 -24
Recommend
More recommend