Download presentation
Presentation is loading. Please wait.
Published byLeon Rich Modified over 9 years ago
1
Synchronicity II Introduction to Operating Systems: Module 6
2
Review u Synchronization The problem of getting processes to work together Poor synchronization can result in a race condition Two people access the same bank account via ATM The naïve solution to the bounded buffer problem u The critical section problem Is an instance of synchronization Formal criteria for a solution Traditional: mutual exclusion, progress, bounded wait Last time: 6 equivalent, less difficult criteria
3
Review u Solutions to the critical section problem (CSP) Software Petersen’s algorithm (2 processes) Bakery algorithm (3 or more processes) Hardware Disable interrupts Special instructions (can’t solve the problem alone) OS primitives (introduced in this module) Semaphores Monitors
4
Software solutions to CSP u Some solutions are hard to program, debug Bakery algorithm u Waiting processes are busy Wastes CPU cycles It would be better to block the process Like waiting for I/O Incurs overhead of a context switch Not efficient for very short critical sections
5
Hardware solutions to CSP: disable interrupts u On a uniprocessor: mutual exclusion is preserved but efficiency of execution is degraded: while in CS, we cannot interleave execution with other processes that are in RS u On a multiprocessor: mutual exclusion is not achieved u Generally not an acceptable solution repeat disable interrupts critical section enable interrupts remainder section forever
6
Hardware solutions to CSP: Special machine instructions u Machine instructions can perform 2 actions atomically (indivisible) on the same memory location (ex: reading and testing) u The execution of such an instruction is mutually exclusive (even with multiple CPUs) u They can be used simply to provide mutual exclusion but need more complex algorithms for satisfying the requirements of the CSP
7
Synchronization Primitives u Semaphores u Monitors
8
Semaphores u A semaphore is an abstract data type u Semaphores can be implemented through Busy wait Blocking via system calls u Semaphores have a 2 method interface Wait( ) Signal( ) Wait Signal Semaphore
9
Busy waiting semaphores u The simplest way to implement semaphores u Useful when critical sections last for a short time, or we have lots of CPUs u I is initialized to positive value (to allow someone in at the beginning) S.wait(){ while (I<=1); I--;} S.signal(){ I++;} I Semaphore Integer
10
Atomicity aspects u The testing and decrementing sequence in wait are atomic, but not the loop u Signal is atomic u No two processes can be allowed to execute atomic sections simultaneously u This can be implemented by other mechanisms, such as test-and-set S.wait: I <= 1 I - - atomic F T
11
Using semaphores for solving critical section problems u For n processes u Initialize I to 1 u Then only 1 process is allowed into CS (mutual exclusion) u To allow k processes into CS, we initialize I to k Process P i : repeat S.wait(); CS S.signal(); RS forever
12
Signal to a waiting process Process P i : repeat S.wait(); CS S.signal(); RS forever Process P j : repeat S.wait(); CS S.signal(); RS forever Semaphores: the global view Initialize I to 1
13
Semaphores synchronize processes u We have 2 processes: P1 and P2 u Statement S1 in P1 needs to be performed before statement S2 in P2 u Then define a semaphore “synch” u Initialize synch to 0 u Proper synchronization is achieved by having in P1: S1; synch.signal(); u And having in P2: synch.wait(); S2;
14
Semaphores: observations u When initial I>=0: the number of processes that can execute S.wait() without being blocked = I I processes can enter the “limited capacity” section u When I becomes >=0, which waiting process enters the critical section? FCFS? Not specified Implementation dependent
15
Avoiding busy wait in semaphores u To avoid busy waiting: when a process has to wait for a semaphore to become greater than 0, it will be put in a blocked queue of processes waiting for this to happen u Queues can be FIFO, priority, etc.: OS has control on the order processes enter CS u In practice, wait and signal become system calls to the OS (such as I/O), which contains the semaphore implementation u There is a queue for every semaphore just as there is a queue for each I/O unit
16
Semaphores without busy waiting class semaphore { private: int I; ProcessQueue queue; public: void signal(); void wait();} u When a process must wait for a semaphore S, it is blocked and put on the semaphore’s queue u The signal operation removes (by a fair policy like FIFO) one process from the queue and puts it in the list of ready processes S.wait() { S.I--; if (S.I<0) S. enqueue(p)} S.signal(){ I++; if (s.I<=0) S.dequeue();} Semaphore Queue -3 I
17
Semaphore’s operations (atomic) S.wait() {S.I--; if (S.I<0) { block this process place this process in S.queue }} S.signal(){S.I++; if (S.I<=0) { remove a process from S.queue place it on ready list }} The value to which S.count is initialized depends on the application
18
Semaphores: implementation u wait and signal themselves contain critical sections! How to implement them? u Note that they are very short critical sections u Solutions: uniprocessor: disable interrupts during these operations (i.e.: for a very short period) This does not work on a multiprocessor machine multiprocessor: use some busy waiting scheme Busy waiting shouldn’t last long
19
Binary semaphores u Similar to counting semaphores except that “count” is Boolean valued u Perhaps simpler to implement u Can do anything counting semaphores can do u Requires writing more code than counting semaphores: must use additional counting variables protected by binary semaphores
20
Binary semaphores waitB(S){ if (S.value = 1) S.value = 0; else { block(this) S.queue.add(this) } signalB(S){ if (S.queue is empty) S.value = 1; else { process = S.queue.next(); readyQueue.add(process); }
21
Semaphores u Semaphores provide a structured tool for enforcing mutual exclusion and coordinate processes. u Avoid bus wait, but not completely. u If used correctly, avoid deadlock and starvation. u But if wait(S) and signal(S) are scattered among several processes it may be difficult to use them correctly u Usage must be correct in all processes u One bad (or malicious) process can fail the entire collection of processes, cause deadlock, starvation
22
Monitors u Are high-level language constructs that provide equivalent functionality to that of semaphores but are easier to control u Found in many concurrent programming languages Concurrent Pascal, Modula-3, C++, Java… u Very appropriate for OO programming u However each language has own ‘dialect’
23
Monitor u Is a software module containing: one or more procedures an initialization sequence local data variables u Characteristics: local variables accessible only by monitor’s procedures a process enters the monitor by invoking one of its procedures only one process can be in the monitor at any given time
24
Monitor u The monitor ensures mutual exclusion: no need to program this constraint explicitly u Shared data within the monitor are protected The monitor locks on process entry Only one process can execute in the monitor at a time u Process synchronization is done by the programmer by using condition variables represent conditions on which a process may wait for before executing in the monitor
25
Condition variables u are local to the monitor (accessible only within the monitor) u have ADT methods: cwait(a): blocks execution of the calling process on condition variable a process can resume execution only if another process executes csignal(a) csignal(a): resume execution of some process blocked on condition variable a If several such process exists: choose any one (fifo or priority) If no such process exists: do nothing
26
Monitor u Awaiting processes are either in the entrance queue or in a condition queue u A process puts itself into condition queue c n by issuing cwait(c n ) u csignal(c n ) brings into the monitor 1 process in condition c n queue u Hence csignal(c n ) blocks the calling process and puts it in the urgent queue (unless csignal is the last operation of the monitor procedure)
27
Monitors for the bounded buffer u Monitor needs to hold the buffer: buffer: array[0..k-1] of items; u needs two condition variables: notfull: csignal(notFull) when buffer becomes not full notempty: csignal(notEmpty) when the becomes not empty u needs buffer pointers and counts: nextin: points to next slot to be filled nextout: points to next item to be taken count: holds the number of items in buffer No race condition: monitor ensures mutual exclusion!
28
Monitor for the bounded P/C problem Monitor boundedbuffer{ items buffer[k]; int nextin=0, nextout=0, count=0; condition notfull, notempty; //buffer state void append(item v){ if (count==k) cwait(notfull); buffer[nextin]= v; nextin++ % k; count++; csignal(notempty);} item take(){item v; if (count==0) cwait(notempty); v= buffer[nextout]; nextout++ % k; count--; csignal(notfull); return v;} }
29
Monitor u Monitors result in simpler, easier to read code, and provide synchronization via condition variables u They are not, however, able to do things semaphores cannot: they can be implemented with semaphores, and vice versa
30
Monitor example Monitor boundedbuffer{ buffer[ | | | ] nextin=0 nextout=0 count=0 k=4 void append(item v){ if (count==k) cwait(notfull); buffer[nextin]= v; nextin++ mod k; count++; csignal(notempty);} item take(){item v; if (count==0) cwait(notempty); v= buffer[nextout]; nextout++ mod k; count--; csignal(notfull); return v;}} notfull notempty Running process
31
Monitor example Monitor boundedbuffer{ buffer[ 1 | | | ]; nextin=0 nextout=0 count=0 k=4 void append(item v){ if (count==k) cwait(notfull); buffer[nextin]= v; nextin++ mod k; count++; csignal(notempty);} item take(){item v; if (count==0) cwait(notempty); v= buffer[nextout]; nextout++ mod k; count--; csignal(notfull); return v;}} notfull notempty
32
Monitor example Monitor boundedbuffer{ buffer[ 1 | | | ] nextin=1 nextout=0 count=0 k=4 void append(item v){ if (count==k) cwait(notfull); buffer[nextin]= v; nextin++ mod k; count++; csignal(notempty);} item take(){item v; if (count==0) cwait(notempty); v= buffer[nextout]; nextout++ mod k; count--; csignal(notfull); return v;}} notfull notempty
33
Monitor example Monitor boundedbuffer{ buffer[ 1 | | | ] nextin=1 nextout=0 count=1 k=4 void append(item v){ if (count==k) cwait(notfull); buffer[nextin]= v; nextin++ mod k; count++; csignal(notempty);} item take(){item v; if (count==0) cwait(notempty); v= buffer[nextout]; nextout++ mod k; count--; csignal(notfull); return v;}} notfull notempty
34
Monitor example Monitor boundedbuffer{ buffer[ 1 | | | ] nextin=1 nextout=0 count=1 k=4 void append(item v){ if (count==k) cwait(notfull); buffer[nextin]= v; nextin++ mod k; count++; csignal(notempty);} item take(){item v; if (count==0) cwait(notempty); v= buffer[nextout]; nextout++ mod k; count--; csignal(notfull); return v;}} notfull notempty
35
Monitor example Monitor boundedbuffer{ buffer[ 1 | | | ] nextin=1 nextout=0 count=1 k=4 void append(item v){ if (count==k) cwait(notfull); buffer[nextin]= v; nextin++ mod k; count++; csignal(notempty);} item take(){item v; if (count==0) cwait(notempty); v= buffer[nextout]; nextout++ mod k; count--; csignal(notfull); return v;}} notfull notempty
36
Monitor example Monitor boundedbuffer{ buffer[ 1 | 2 | | ] nextin=1 nextout=0 count=1 k=4 void append(item v){ if (count==k) cwait(notfull); buffer[nextin]= v; nextin++ mod k; count++; csignal(notempty);} item take(){item v; if (count==0) cwait(notempty); v= buffer[nextout]; nextout++ mod k; count--; csignal(notfull); return v;}} notfull notempty
37
Monitor example Monitor boundedbuffer{ buffer[ 1 | 2 | | ] nextin=2 nextout=0 count=1 k=4 void append(item v){ if (count==k) cwait(notfull); buffer[nextin]= v; nextin++ mod k; count++; csignal(notempty);} item take(){item v; if (count==0) cwait(notempty); v= buffer[nextout]; nextout++ mod k; count--; csignal(notfull); return v;}} notfull notempty
38
Monitor example Monitor boundedbuffer{ buffer[ 1 | 2 | | ] nextin=2 nextout=0 count=2 k=4 void append(item v){ if (count==k) cwait(notfull); buffer[nextin]= v; nextin++ mod k; count++; csignal(notempty);} item take(){item v; if (count==0) cwait(notempty); v= buffer[nextout]; nextout++ mod k; count--; csignal(notfull); return v;}} notfull notempty
39
Monitor example Monitor boundedbuffer{ buffer[ 1 | 2 | | ] nextin=2 nextout=0 count=2 k=4 void append(item v){ if (count==k) cwait(notfull); buffer[nextin]= v; nextin++ mod k; count++; csignal(notempty);} item take(){item v; if (count==0) cwait(notempty); v= buffer[nextout]; nextout++ mod k; count--; csignal(notfull); return v;}} notfull notempty
40
Monitor example Monitor boundedbuffer{ buffer[ 1 | 2 | | ] nextin=2 nextout=0 count=2 k=4 void append(item v){ if (count==k) cwait(notfull); buffer[nextin]= v; nextin++ mod k; count++; csignal(notempty);} item take(){item v; if (count==0) cwait(notempty); v= buffer[nextout]; nextout++ mod k; count--; csignal(notfull); return v;}} notfull notempty
41
Monitor example Monitor boundedbuffer{ buffer[ 1 | 2 | | ] nextin=2 nextout=0 count=2 k=4 void append(item v){ if (count==k) cwait(notfull); buffer[nextin]= v; nextin++ mod k; count++; csignal(notempty);} item take(){item v; if (count==0) cwait(notempty); v= buffer[nextout]; nextout++ mod k; count--; csignal(notfull); return v;}} notfull notempty
42
Monitor example Monitor boundedbuffer{ buffer[ 1 | 2 | | ] nextin=2 nextout=1 count=2 k=4 void append(item v){ if (count==k) cwait(notfull); buffer[nextin]= v; nextin++ mod k; count++; csignal(notempty);} item take(){item v; if (count==0) cwait(notempty); v= buffer[nextout]; nextout++ mod k; count--; csignal(notfull); return v;}} notfull notempty
43
Monitor example Monitor boundedbuffer{ buffer[ 1 | 2 | | ] nextin=2 nextout=1 count=1 k=4 void append(item v){ if (count==k) cwait(notfull); buffer[nextin]= v; nextin++ mod k; count++; csignal(notempty);} item take(){item v; if (count==0) cwait(notempty); v= buffer[nextout]; nextout++ mod k; count--; csignal(notfull); return v;}} notfull notempty
44
Monitor example Monitor boundedbuffer{ buffer[ 1 | 2 | | ] nextin=2 nextout=1 count=1 k=4 void append(item v){ if (count==k) cwait(notfull); buffer[nextin]= v; nextin++ mod k; count++; csignal(notempty);} item take(){item v; if (count==0) cwait(notempty); v= buffer[nextout]; nextout++ mod k; count--; csignal(notfull); return v;}} notfull notempty
45
Monitor example Monitor boundedbuffer{ buffer[ 1 | 2 | | ] nextin=2 nextout=1 count=1 k=4 void append(item v){ if (count==k) cwait(notfull); buffer[nextin]= v; nextin++ mod k; count++; csignal(notempty);} item take(){item v; if (count==0) cwait(notempty); v= buffer[nextout]; nextout++ mod k; count--; csignal(notfull); return v;}} notfull notempty
46
Monitor example Monitor boundedbuffer{ buffer[ 1 | 2 | 3 | ] nextin=2 nextout=1 count=1 k=4 void append(item v){ if (count==k) cwait(notfull); buffer[nextin]= v; nextin++ mod k; count++; csignal(notempty);} item take(){item v; if (count==0) cwait(notempty); v= buffer[nextout]; nextout++ mod k; count--; csignal(notfull); return v;}} notfull notempty
47
Monitor example Monitor boundedbuffer{ buffer[ 1 | 2 | 3 | ] nextin=3 nextout=1 count=1 k=4 void append(item v){ if (count==k) cwait(notfull); buffer[nextin]= v; nextin++ mod k; count++; csignal(notempty);} item take(){item v; if (count==0) cwait(notempty); v= buffer[nextout]; nextout++ mod k; count--; csignal(notfull); return v;}} notfull notempty
48
Monitor example Monitor boundedbuffer{ buffer[ 1 | 2 | 3 | ] nextin=3 nextout=1 count=2 k=4 void append(item v){ if (count==k) cwait(notfull); buffer[nextin]= v; nextin++ mod k; count++; csignal(notempty);} item take(){item v; if (count==0) cwait(notempty); v= buffer[nextout]; nextout++ mod k; count--; csignal(notfull); return v;}} notfull notempty
49
Monitor example Monitor boundedbuffer{ buffer[ 1 | 2 | 3 | ] nextin=3 nextout=1 count=2 k=4 void append(item v){ if (count==k) cwait(notfull); buffer[nextin]= v; nextin++ mod k; count++; csignal(notempty);} item take(){item v; if (count==0) cwait(notempty); v= buffer[nextout]; nextout++ mod k; count--; csignal(notfull); return v;}} notfull notempty
50
Monitor example Monitor boundedbuffer{ buffer[ 1 | 2 | 3 | ] nextin=3 nextout=1 count=2 k=4 void append(item v){ if (count==k) cwait(notfull); buffer[nextin]= v; nextin++ mod k; count++; csignal(notempty);} item take(){item v; if (count==0) cwait(notempty); v= buffer[nextout]; nextout++ mod k; count--; csignal(notfull); return v;}} notfull notempty
51
Monitor example Monitor boundedbuffer{ buffer[ 1 | 2 | 3 | 4 ] nextin=3 nextout=1 count=2 k=4 void append(item v){ if (count==k) cwait(notfull); buffer[nextin]= v; nextin++ mod k; count++; csignal(notempty);} item take(){item v; if (count==0) cwait(notempty); v= buffer[nextout]; nextout++ mod k; count--; csignal(notfull); return v;}} notfull notempty
52
Monitor example Monitor boundedbuffer{ buffer[ 1 | 2 | 3 | 4 ] nextin=0 nextout=1 count=2 k=4 void append(item v){ if (count==k) cwait(notfull); buffer[nextin]= v; nextin++ mod k; count++; csignal(notempty);} item take(){item v; if (count==0) cwait(notempty); v= buffer[nextout]; nextout++ mod k; count--; csignal(notfull); return v;}} notfull notempty
53
Monitor example Monitor boundedbuffer{ buffer[ 1 | 2 | 3 | 4 ] nextin=0 nextout=1 count=3 k=4 void append(item v){ if (count==k) cwait(notfull); buffer[nextin]= v; nextin++ mod k; count++; csignal(notempty);} item take(){item v; if (count==0) cwait(notempty); v= buffer[nextout]; nextout++ mod k; count--; csignal(notfull); return v;}} notfull notempty
54
Monitor example Monitor boundedbuffer{ buffer[ 1 | 2 | 3 | 4 ] nextin=0 nextout=1 count=3 k=4 void append(item v){ if (count==k) cwait(notfull); buffer[nextin]= v; nextin++ mod k; count++; csignal(notempty);} item take(){item v; if (count==0) cwait(notempty); v= buffer[nextout]; nextout++ mod k; count--; csignal(notfull); return v;}} notfull notempty
55
Monitor example Monitor boundedbuffer{ buffer[ 1 | 2 | 3 | 4 ] nextin=0 nextout=1 count=3 k=4 void append(item v){ if (count==k) cwait(notfull); buffer[nextin]= v; nextin++ mod k; count++; csignal(notempty);} item take(){item v; if (count==0) cwait(notempty); v= buffer[nextout]; nextout++ mod k; count--; csignal(notfull); return v;}} notfull notempty
56
Monitor example Monitor boundedbuffer{ buffer[ 5 | 2 | 3 | 4 ] nextin=0 nextout=1 count=3 k=4 void append(item v){ if (count==k) cwait(notfull); buffer[nextin]= v; nextin++ mod k; count++; csignal(notempty);} item take(){item v; if (count==0) cwait(notempty); v= buffer[nextout]; nextout++ mod k; count--; csignal(notfull); return v;}} notfull notempty
57
Monitor example Monitor boundedbuffer{ buffer[ 5 | 2 | 3 | 4 ] nextin=1 nextout=1 count=3 k=4 void append(item v){ if (count==k) cwait(notfull); buffer[nextin]= v; nextin++ mod k; count++; csignal(notempty);} item take(){item v; if (count==0) cwait(notempty); v= buffer[nextout]; nextout++ mod k; count--; csignal(notfull); return v;}} notfull notempty
58
Monitor example Monitor boundedbuffer{ buffer[ 5 | 2 | 3 | 4 ] nextin=1 nextout=1 count=4 k=4 void append(item v){ if (count==k) cwait(notfull); buffer[nextin]= v; nextin++ mod k; count++; csignal(notempty);} item take(){item v; if (count==0) cwait(notempty); v= buffer[nextout]; nextout++ mod k; count--; csignal(notfull); return v;}} notfull notempty
59
Monitor example Monitor boundedbuffer{ buffer[ 5 | 2 | 3 | 4 ] nextin=1 nextout=1 count=4 k=4 void append(item v){ if (count==k) cwait(notfull); buffer[nextin]= v; nextin++ mod k; count++; csignal(notempty);} item take(){item v; if (count==0) cwait(notempty); v= buffer[nextout]; nextout++ mod k; count--; csignal(notfull); return v;}} notfull notempty
60
Monitor example Monitor boundedbuffer{ buffer[ 5 | 2 | 3 | 4 ] nextin=1 nextout=1 count=4 k=4 void append(item v){ if (count==k) cwait(notfull); buffer[nextin]= v; nextin++ mod k; count++; csignal(notempty);} item take(){item v; if (count==0) cwait(notempty); v= buffer[nextout]; nextout++ mod k; count--; csignal(notfull); return v;}} notfull notempty
61
Monitor example Monitor boundedbuffer{ buffer[ 5 | 2 | 3 | 4 ] nextin=1 nextout=1 count=4 k=4 void append(item v){ if (count==k) cwait(notfull); buffer[nextin]= v; nextin++ mod k; count++; csignal(notempty);} item take(){item v; if (count==0) cwait(notempty); v= buffer[nextout]; nextout++ mod k; count--; csignal(notfull); return v;}} notfull notempty
62
Monitor example Monitor boundedbuffer{ buffer[ 5 | 2 | 3 | 4 ] nextin=1 nextout=2 count=4 k=4 void append(item v){ if (count==k) cwait(notfull); buffer[nextin]= v; nextin++ mod k; count++; csignal(notempty);} item take(){item v; if (count==0) cwait(notempty); v= buffer[nextout]; nextout++ mod k; count--; csignal(notfull); return v;}} notfull notempty
63
Monitor example Monitor boundedbuffer{ buffer[ 5 | 2 | 3 | 4 ] nextin=1 nextout=2 count=3 k=4 void append(item v){ if (count==k) cwait(notfull); buffer[nextin]= v; nextin++ mod k; count++; csignal(notempty);} item take(){item v; if (count==0) cwait(notempty); v= buffer[nextout]; nextout++ mod k; count--; csignal(notfull); return v;}} notfull notempty
64
Monitor example Monitor boundedbuffer{ buffer[ 5 | 2 | 3 | 4 ] nextin=1 nextout=2 count=3 k=4 void append(item v){ if (count==k) cwait(notfull); buffer[nextin]= v; nextin++ mod k; count++; csignal(notempty);} item take(){item v; if (count==0) cwait(notempty); v= buffer[nextout]; nextout++ mod k; count--; csignal(notfull); return v;}} notfull notempty
65
Monitor example Monitor boundedbuffer{ buffer[ 5 | 2 | 3 | 4 ] nextin=1 nextout=2 count=3 k=4 void append(item v){ if (count==k) cwait(notfull); buffer[nextin]= v; nextin++ mod k; count++; csignal(notempty);} item take(){item v; if (count==0) cwait(notempty); v= buffer[nextout]; nextout++ mod k; count--; csignal(notfull); return v;}} notfull notempty
66
Monitor example Monitor boundedbuffer{ buffer[ 5 | 6 | 3 | 4 ] nextin=1 nextout=2 count=3 k=4 void append(item v){ if (count==k) cwait(notfull); buffer[nextin]= v; nextin++ mod k; count++; csignal(notempty);} item take(){item v; if (count==0) cwait(notempty); v= buffer[nextout]; nextout++ mod k; count--; csignal(notfull); return v;}} notfull notempty
67
Monitor example Monitor boundedbuffer{ buffer[ 5 | 6 | 3 | 4 ] nextin=2 nextout=2 count=3 k=4 void append(item v){ if (count==k) cwait(notfull); buffer[nextin]= v; nextin++ mod k; count++; csignal(notempty);} item take(){item v; if (count==0) cwait(notempty); v= buffer[nextout]; nextout++ mod k; count--; csignal(notfull); return v;}} notfull notempty
68
Monitor example Monitor boundedbuffer{ buffer[ 5 | 6 | 3 | 4 ] nextin=2 nextout=2 count=4 k=4 void append(item v){ if (count==k) cwait(notfull); buffer[nextin]= v; nextin++ mod k; count++; csignal(notempty);} item take(){item v; if (count==0) cwait(notempty); v= buffer[nextout]; nextout++ mod k; count--; csignal(notfull); return v;}} notfull notempty
69
Monitor example Monitor boundedbuffer{ buffer[ 5 | 6 | 3 | 4 ] nextin=2 nextout=2 count=4 k=4 void append(item v){ if (count==k) cwait(notfull); buffer[nextin]= v; nextin++ mod k; count++; csignal(notempty);} item take(){item v; if (count==0) cwait(notempty); v= buffer[nextout]; nextout++ mod k; count--; csignal(notfull); return v;}} notfull notempty
70
Monitor example Monitor boundedbuffer{ buffer[ 5 | 6 | 3 | 4 ] nextin=2 nextout=2 count=4 k=4 void append(item v){ if (count==k) cwait(notfull); buffer[nextin]= v; nextin++ mod k; count++; csignal(notempty);} item take(){item v; if (count==0) cwait(notempty); v= buffer[nextout]; nextout++ mod k; count--; csignal(notfull); return v;}} notfull notempty
71
Monitor example Monitor boundedbuffer{ buffer[ 5 | 6 | 3 | 4 ] nextin=2 nextout=2 count=4 k=4 void append(item v){ if (count==k) cwait(notfull); buffer[nextin]= v; nextin++ mod k; count++; csignal(notempty);} item take(){item v; if (count==0) cwait(notempty); v= buffer[nextout]; nextout++ mod k; count--; csignal(notfull); return v;}} notfull notempty
72
Monitor example Monitor boundedbuffer{ buffer[ 5 | 6 | 3 | 4 ] nextin=2 nextout=2 count=4 k=4 void append(item v){ if (count==k) cwait(notfull); buffer[nextin]= v; nextin++ mod k; count++; csignal(notempty);} item take(){item v; if (count==0) cwait(notempty); v= buffer[nextout]; nextout++ mod k; count--; csignal(notfull); return v;}} notfull notempty
73
Monitor example Monitor boundedbuffer{ buffer[ 5 | 6 | 3 | 4 ] nextin=2 nextout=2 count=4 k=4 void append(item v){ if (count==k) cwait(notfull); buffer[nextin]= v; nextin++ mod k; count++; csignal(notempty);} item take(){item v; if (count==0) cwait(notempty); v= buffer[nextout]; nextout++ mod k; count--; csignal(notfull); return v;}} notfull notempty
74
Monitor example Monitor boundedbuffer{ buffer[ 5 | 6 | 3 | 4 ] nextin=2 nextout=2 count=4 k=4 void append(item v){ if (count==k) cwait(notfull); buffer[nextin]= v; nextin++ mod k; count++; csignal(notempty);} item take(){item v; if (count==0) cwait(notempty); v= buffer[nextout]; nextout++ mod k; count--; csignal(notfull); return v;}} notfull notempty
75
Monitor example Monitor boundedbuffer{ buffer[ 5 | 6 | 3 | 4 ] nextin=2 nextout=2 count=4 k=4 void append(item v){ if (count==k) cwait(notfull); buffer[nextin]= v; nextin++ mod k; count++; csignal(notempty);} item take(){item v; if (count==0) cwait(notempty); v= buffer[nextout]; nextout++ mod k; count--; csignal(notfull); return v;}} notfull notempty
76
Monitor example Monitor boundedbuffer{ buffer[ 5 | 6 | 3 | 4 ] nextin=2 nextout=3 count=4 k=4 void append(item v){ if (count==k) cwait(notfull); buffer[nextin]= v; nextin++ mod k; count++; csignal(notempty);} item take(){item v; if (count==0) cwait(notempty); v= buffer[nextout]; nextout++ mod k; count--; csignal(notfull); return v;}} notfull notempty
77
Monitor example Monitor boundedbuffer{ buffer[ 5 | 6 | 3 | 4 ] nextin=2 nextout=3 count=3 k=4 void append(item v){ if (count==k) cwait(notfull); buffer[nextin]= v; nextin++ mod k; count++; csignal(notempty);} item take(){item v; if (count==0) cwait(notempty); v= buffer[nextout]; nextout++ mod k; count--; csignal(notfull); return v;}} notfull notempty
78
Monitor example Monitor boundedbuffer{ buffer[ 5 | 6 | 3 | 4 ] nextin=2 nextout=3 count=3 k=4 void append(item v){ if (count==k) cwait(notfull); buffer[nextin]= v; nextin++ mod k; count++; csignal(notempty);} item take(){item v; if (count==0) cwait(notempty); v= buffer[nextout]; nextout++ mod k; count--; csignal(notfull); return v;}} notfull notempty Who goes first?
79
u When a condition variable with a nonempty queue is signaled, which process executes in the monitor? The signaled process: Hoare semantics The signaling process: Mesa (Brinch-Hansen) semantics u If the signaled process does not immediately execute in the monitor, it is possible that the signaled condition could be come invalid Using Mesa semantics the signaled process must recheck the condition, waiting on the associated condition variable if it is false
80
Hoare vs. Mesa semantics: usage Monitor boundedbuffer{ items buffer[k-1]; int nextin=0, nextout=0; int count=0; condition notfull, notempty; void append(item v){ if (count==k) cwait(notfull); buffer[nextin]= v; nextin++ % k; count++; csignal(notempty);} item take(){item v; if (count==0) cwait(notempty); v= buffer[nextout]; nextout++ % k; count--; csignal(notfull); return v;} } Monitor boundedbuffer{ items buffer[k-1]; int nextin=0, nextout=0; int count=0; condition notfull, notempty; void append(item v){ while(count==k) cwait(notfull); buffer[nextin]= v; nextin++ % k; count++; csignal(notempty);} item take(){item v; while(count==0) cwait(notempty); v= buffer[nextout]; nextout++ % k; count--; csignal(notfull); return v;} }
81
Message passing u Processes (and threads) can communicate without synchronization Shared memory u A message passing paradigm for communication requires synchronization Send (destination, message) What if the source has not yet called receive? Receive(source, message) What if no message was sent?
82
Blocking vs. non-blocking u After calling send, if no matching receive The sender could block until the message is received The sender could continue u After calling receive, if no matching send The caller could block until a message is sent Test function (Are there pending messages?) Time out (Wait until message or X seconds have passed) The caller could continue, with receive returning failure
83
Direct vs. Indirect u If the source/destination arguments are process identifiers, the system uses direct messaging u If the source/destination arguments are mailboxes, possibly shared by many processes, the system uses indirect messaging Many senders, one receiver (client server) Many receivers, many senders (topic subscription) Who owns the mailbox?
84
Message passing as synchronization u Semaphores or monitors may be used to implement message passing u A message passing system can be used to implement monitors or semaphores u Message passing has the same synchronization power as semaphores and monitors
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.