170 likes | 269 Views
Semaphore Interface. S : Integer value Down(S): If (S == 0) block else if (S > 0) S = S – 1 Up(S): If any blocked processes, Release one of them else S = S + 1. Atomic actions Down might block Up never blocks.
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