170 likes | 282 Vues
This document explores the implementation of semaphores for managing process synchronization in operating systems. It details the Down and Up operations, which control access to shared resources by managing a semaphore variable and a queue for blocked processes. The behavior of semaphores is examined, highlighting their non-blocking and blocking nature. Various synchronization techniques including mutex, test-and-set locks, and POSIX mutexes are discussed, along with message passing as an alternative method for process interaction. Real-world examples illustrate how these concepts are applied effectively in concurrent programming.
E N D
Semaphore Interface • S: Integer value • Down(S):If (S == 0) blockelse if (S > 0) S = S – 1 • Up(S):If any blocked processes, Release one of themelse S = S + 1 • Atomic actions • Down might block • Up never blocks Cpr E 308
Down(S): if (S == 0) then suspend process and add to Q; else S = S-1 Up(S):if (Q non-empty) dequeue a process and make it runnable; else S = S+1 Semaphore Implementation Data Structures:Integer SQueue of processes, Q Cpr E 308
Down(S): lock (mutex) if (S == 0) then suspend process and add to Q; unlock(mutex); switch to another process else S = S-1;unlock(mutex); Semaphore Implementation Data Structures:Integer SQueue of processes, Q Up(S): • lock (mutex) • if (Q non-empty) then • dequeue a process and make it runnable • unlock(mutex); else S = S+1;unlock(mutex); Cpr E 308
How is mutex implemented in this case? • Using a semaphore? No • Peterson’s algorithm? Ok • Test-and-set-lock? Better • In the kernel: disable interrupts Best Cpr E 308
Uni vs Multi processors • Disabling interrupts does not work on multiprocessors. Why? • Test and set - best bet Cpr E 308
Semaphore Example:Implementing wait() system call • Parent does a wait() call on child • wait till child finishes before exiting • What if parent executed wait() after child exited? Cpr E 308
Parent and Child 0 Cpr E 308
Child exits late 1 0 Busy waiting expensive, go to sleep Cpr E 308
Parent Sleeps 1 0 wakeup Cpr E 308
Child exits early 1 Cpr E 308
Simultaneous 1 0 wakeup Cpr E 308
Solution: Semaphore • Semaphore zombie: initialize to 0 • Parent:down(zombie) inside wait() • Child:up(zombie) upon exiting Cpr E 308
POSIX mutexes • int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr); • int pthread_mutex_lock(pthread_mutex_t *mutex)); • int pthread_mutex_trylock(pthread_mutex_t *mutex); • int pthread_mutex_unlock(pthread_mutex_t *mutex); • int pthread_mutex_destroy(pthread_mutex_t *mutex); • “man pthread_mutex_init” on your Linux machine Cpr E 308
POSIX Semaphores • int sem_init(sem_t *sem, int pshared, unsigned int value); • int sem_wait(sem_t * sem); • int sem_trywait(sem_t * sem); • int sem_post(sem_t * sem); • int sem_getvalue(sem_t * sem, int * sval); • int sem_destroy(sem_t * sem); Cpr E 308
Message Passing • No shared variables • send (destination, message) • receive (destination, message)blocks till a message arrives Cpr E 308
Issues • Across different machines, message passing is the real thing • On the same machine (shared physical memory), performance? • Marshaling data into messages • Provide reliable transmission across unreliable links? • Event-driven mode of programming Cpr E 308
Producer-Consumer using Message Passing Cpr E 308