210 likes | 290 Views
4061 Session 20 (3/29). Today. Posix Threads Howto Leftovers Intro to Synchronization Issues. Today’s Objectives. Explain how multiple threads can get into trouble using shared data. Give an example. Define mutual exclusion, critical sections, and race conditions.
E N D
Today • Posix Threads Howto Leftovers • Intro to Synchronization Issues
Today’s Objectives • Explain how multiple threads can get into trouble using shared data. • Give an example. • Define mutual exclusion, critical sections, and race conditions. • Explain why it’s not easy to ensure mutual exclusion between threads, and give an example of how a mutex might be implemented in an OS. • Write multi-threaded programs that use POSIX mutexes for synchronization.
Admin • Quiz 4 next Thursday
The Trouble With Threads • Concurrent access to shared data? • Is everyone just reading? We’re ok. • Is someone writing? Unsafe.
Concepts • Situations where two or more processes are reading or writing some shared data and the final result depends on who runs when are called race conditions. • The section of code where a thread accesses a shared resource non-atomically is known as a critical section. • Today is about learning some tools that we can use to synchronize access between threads to stay safe.
Mutual Exclusion • We wish to prohibit multiple threads from accessing shared data at the same time • We call this mutual exclusion • Shorthand: mutex • The design of primitives to enforce mutual exclusion is a central part of OS design • Take 5103 and you get to implement these primitives yourself
Avoiding Race Conditions • Four conditions to avoid race conditions: • No two threads simultaneously in critical region • No assumptions made about speeds or numbers of CPUs • No thread running outside its critical region may block another thread • No thread must wait forever to enter its critical region
Bad Solution 1 • Disable Interrupts • How does this help? • Do we really want to allow user processes to disable interrupts? (what are the consequences in a multi-user system?) • Will this work on a multi-CPU system? • Conclusion: The OS may wish to disable interrupts as part of a mutex implementation
Bad Solution 2 • Lock Variable int lock = 0while (lock)lock=1do critical section lock=0 • What’s wrong with this solution? Remember that context switches can happen at any time.
Hardware Support Helps • Test and Set Lock instruction • Example: TSL RX, LOCK • All at once: • read the contents of LOCK into register RX • Store nonzero value in LOCK • How can we use this crazy instuction?
Priority Inversion • Hmm...one more problem • enter_region guarantees mutex, but it uses busy waiting. • Inefficient, and... • The priority inversion problem • Two processes, H and L (high and low priority). H runs whenever it is in “ready” state, L never runs when H is ready. • L holds a lock • H wakes up from an I/O operation and decides that it wants that lock. • (Thus, L is really the highest-priority process here)
Achieving Mutual Exclusion • Finding critical sections in code can be hard (debugging typically won’t work) • Luckily, the mechanisms built into UNIX make *implementing* mutex pretty easy. • Some possibilities • File locks • Pipes • Semaphores • POSIX mutex
POSIX Mutex • What is a POSIX Mutex? • It’s a variable that can be either locked or unlocked. • If the mutex is locked, then there is a thread that is said to “hold” the mutex. • Meant to be used for short periods of time.
Many Threads • So what if there are many threads that all want access to the same data? • POSIX mutex maintains a queue of processes that wish to hold the mutex. • POSIX does not guarantee the order in which processes in the queue obtain the mutex.
Mutex Interface • pthread_mutex_init • pthread_mutex_destroy • pthread_mutex_lock • pthread_mutex_trylock • pthread_mutex_unlock