Synchronization semaphores and some more stuff Operating Systems

  • Slides: 55
Download presentation
Synchronization: semaphores and some more stuff Operating Systems, Spring 2020, Dinur , Hendler and

Synchronization: semaphores and some more stuff Operating Systems, Spring 2020, Dinur , Hendler and Kogan-Sadetsky 1

What's wrong with busy waiting? The mutual exclusion algorithms we saw used busy-waiting. What’s

What's wrong with busy waiting? The mutual exclusion algorithms we saw used busy-waiting. What’s wrong with that? q Doesn't make sense for uni-processor o May cause deadlock q Wastes CPU time o But may be efficient if waiting-time is short Operating Systems, Spring 2020, Dinur , Hendler and Kogan-Sadetsky 2

What's wrong with busy waiting? Busy waiting may cause deadlock q Process A's priority

What's wrong with busy waiting? Busy waiting may cause deadlock q Process A's priority is higher than process B's q Process B enters the CS q Process A needs to enter the CS, busy-waits for B to exit the CS q Process B cannot execute as long as the higher-priority process A is executing/ready Operating Systems, Spring 2020, Dinur , Hendler and Kogan-Sadetsky 3

Outline q Semaphores and the producer/consumer problem q Counting semaphores from binary semaphores q

Outline q Semaphores and the producer/consumer problem q Counting semaphores from binary semaphores q Event counters and message passing synchronization Operating Systems, Spring 2020, Dinur , Hendler and Kogan-Sadetsky 4

Semaphores Two atomic operations are supported by a semaphore S: down(S) [the 'p' operation]

Semaphores Two atomic operations are supported by a semaphore S: down(S) [the 'p' operation] q q If S=0 the process is blocked. It will resume execution only after it is woken-up Else S-- up(S) [the 'v' operation] q If there are blocked processes, wake-up one of them q Else S++ q Up – create a new “entry permit” q Down – consume an “entry permit” if one exists or wait for one q S is non-negative q Supported by Windows, Unix, … Operating Systems, Spring 2020, Dinur , Hendler and Kogan-Sadetsky 5

Semaphores: is the following correct? Two atomic operations are supported by a semaphore S:

Semaphores: is the following correct? Two atomic operations are supported by a semaphore S: down(S) [the 'p' operation] q q If S≤ 0 the process is blocked. It will resume execution only after it is woken-up S-- up(S) [the 'v' operation] q S++ q If there are blocked processes, wake-up one of them q Up – create a new “entry permit” q Down – consume an “entry permit” if one exists or wait for one Operating Systems, Spring 2020, Dinur , Hendler and Kogan-Sadetsky 6

Pseudo-code in previous slide is wrong Consider the following bad sceneario: q S=0 and

Pseudo-code in previous slide is wrong Consider the following bad sceneario: q S=0 and process A performs down(S) – A is blocked q Process B performs up(S) – S=1 A is ready q Process C performs down(S) – S=0 & C proceeds q Process A gets a time-slice and proceeds – S=-1 A single up() freed 2 down()s 7

Implementing mutex with semaphores Shared data: semaphore lock; /* initially lock = 1 */

Implementing mutex with semaphores Shared data: semaphore lock; /* initially lock = 1 */ down(lock) Critical section up(lock) Yes Does it satisfy deadlock-freedom? Yes Does it satisfy starvation-freedom? Depends… Does the algorithm satisfy mutex? Operating Systems, Spring 2020, Dinur , Hendler and Kogan-Sadetsky 8

Operating Systems, Spring 2020, Dinur , Hendler and Kogan-Sadetsky 9

Operating Systems, Spring 2020, Dinur , Hendler and Kogan-Sadetsky 9

More on synchronization using semaphores Three processes p 1; p 2; p 3 semaphores

More on synchronization using semaphores Three processes p 1; p 2; p 3 semaphores p 1 down(s 1); s 1 A up(s 2); s 2 s 1 = 1, s 2 = 0; p 2 down(s 2); s 2 B up(s 2); s 2 p 3 down(s 2); s 2 C up(s 1); s 1 Which execution orders of A, B, C, are possible? (A B* C)* Operating Systems, Spring 2020, Dinur , Hendler and Kogan-Sadetsky 10

No guarantee for correct synchronization (when multiple semaphores/locks are used) P 0 P 1

No guarantee for correct synchronization (when multiple semaphores/locks are used) P 0 P 1 down(S); down(Q); move 1 up(S); up(Q) down(Q); down(S); move 2 up(Q); up(S); 1 1 q Example: move money between two accounts which are protected by semaphores S and Q Does this work? Deadlock! Operating Systems, Spring 2020, Dinur , Hendler and Kogan-Sadetsky 11

Negative-valued semaphores Two atomic operations are supported by a semaphore S: down(S) q q

Negative-valued semaphores Two atomic operations are supported by a semaphore S: down(S) q q S-If S<0 the process is blocked. It will resume execution only when it is woken up up(S) q S++ q If there are blocked processes (i. e. S≤ 0), wake-up one of them q If S is negative, then there are -S blocked processes Operating Systems, Spring 2020, Dinur , Hendler and Kogan-Sadetsky 12

Negative semaphore Implementation type semaphore = record value: integer; L: list of processes; end;

Negative semaphore Implementation type semaphore = record value: integer; L: list of processes; end; -3 L atomic down(S): S. value--; if (S. value < 0) { add this process to S. L; sleep; } atomic up(S): S. value++; if (S. value <= 0) { remove a process P from S. L; wakeup(P); } Operating Systems, Spring 2020, Dinur , Hendler and Kogan-Sadetsky 13

Implementing a spin-lock with TSL (test-set-lock) mutex_lock: TSL CMP JZE CALL JMP ok: RET

Implementing a spin-lock with TSL (test-set-lock) mutex_lock: TSL CMP JZE CALL JMP ok: RET REG, mutex REG, #0 ok thread_yield mutex_lock mutex_unlock: MOV mutex, #0 RET Operating Systems, Spring 2020, Dinur , Hendler and Kogan-Sadetsky 14

Implementing a negative semaphore with TSL type semaphore = record value, flag: integer; L:

Implementing a negative semaphore with TSL type semaphore = record value, flag: integer; L: list of process; end; down(S): repeat until test-and-set(S. flag) S. value--; if (S. value < 0) { add this process to S. L; S. flag=0 sleep; } else S. flag=0 -3 L up(S): repeat until test-and-set(S. flag) S. value++; if (S. value <= 0) { remove a process P from S. L; wakeup(P); } S. flag=0 Any problem with this code? In down(), resetting flag and sleeping should be atomic. System “puts thread to sleep”, only then releases lock Operating Systems, Spring 2020, Dinur , Hendler and Kogan-Sadetsky 15

More on semaphore implementation q On a uni-processor, disabling interrupts may be used q

More on semaphore implementation q On a uni-processor, disabling interrupts may be used q TSL implementation works for multi-processors q On a multi-processor, we can use spin-lock mutual exclusion to protect semaphore access Why is this better than busy-waiting in the first place? Busy-waiting is now guaranteed to be very short Operating Systems, Spring 2020, Dinur , Hendler and Kogan-Sadetsky 16

Producer-Consumer Problem buffer in out q Paradigm for cooperating processes, • producer process produces

Producer-Consumer Problem buffer in out q Paradigm for cooperating processes, • producer process produces information that is consumed by a consumer process q Two versions • unbounded-buffer places no practical limit on the size of the buffer • bounded-buffer assumes that there is a fixed buffer size Operating Systems, Spring 2020, Dinur , Hendler and Kogan-Sadetsky 17

Bounded Buffer buffer 0 1 2 item 1 3 item 2 producer 2 Out

Bounded Buffer buffer 0 1 2 item 1 3 item 2 producer 2 Out 4 item 3 consumer 5 item 4 6 In 7 Operating Systems, Spring 2020, Dinur , Hendler and Kogan-Sadetsky 18

Implementation using semaphores q Two processes or more use a shared buffer in memory

Implementation using semaphores q Two processes or more use a shared buffer in memory q The buffer has finite size(i. e. , it is bounded) bounded q The producer writes to the buffer and the consumer reads from it q A full buffer stops the producer q An empty buffer stops the consumer Operating Systems, Spring 2020, Dinur , Hendler and Kogan-Sadetsky 19

Producer-Consumer implementation with semaphores #define N 100 /* Buffer size */ semaphore mutex =

Producer-Consumer implementation with semaphores #define N 100 /* Buffer size */ semaphore mutex = 1; empty = N; full = 0; /* access control to critical section */ /* counts empty buffer slots */ /* counts full slots */ void producer(void) { int item; while(TRUE) { produce_item(&item); /* generate something. . . */ down(&empty); /* decrement count of empty */ down(&mutex); /* enter critical section */ down enter_item(item); /* insert into buffer */ up(&mutex); /* leave critical section */ up up(&full); /* increment count of full slots */ up } } Operating Systems, Spring 2020, Dinur , Hendler and Kogan-Sadetsky 20

Producer-Consumer implementation with semaphores void consumer(void) consumer { int } item; while(TRUE) { down(&full);

Producer-Consumer implementation with semaphores void consumer(void) consumer { int } item; while(TRUE) { down(&full); down(&mutex); down remove_item(&item); up(&mutex); up up(&empty); up consume_item(item); } /* decrement count of full */ /* enter critical section */ /* take item from buffer) */ /* leave critical section */ /* update count of empty */ /* do something. . . */ Operating Systems, Spring 2020, Dinur , Hendler and Kogan-Sadetsky 21

Outline q Semaphores and the producer/consumer problem q Counting semaphores from binary semaphores q

Outline q Semaphores and the producer/consumer problem q Counting semaphores from binary semaphores q Event counters and message passing synchronization Operating Systems, Spring 2020, Dinur , Hendler and Kogan-Sadetsky 22

Binary Semaphore q Assumes only values 0 or 1 q Wait blocks if semaphore=0

Binary Semaphore q Assumes only values 0 or 1 q Wait blocks if semaphore=0 q Signal (up operation) either wakes up a waiting process, if there is one, or sets value to 1 (if value is already 1, signal is “wasted”) q How can we implement a counting semaphore by using binary semaphores? Operating Systems, Spring 2020, Dinur , Hendler and Kogan-Sadetsky 23

Implementing a counting semaphore from binary semaphores (user space): take 1 binary-semaphore S 1

Implementing a counting semaphore from binary semaphores (user space): take 1 binary-semaphore S 1 initially 1, S 2 initially 0, S. value initially 1 down(S): down(S 1); S. value--; if(S. value < 0){ L 1: up(S 1); L 2: down(S 2); } else up(S 1); up(S): down(S 1); S. value++; if(S. value ≤ 0) up(S 2); up(S 1) This code does not work. Why? Operating Systems, Spring 2020, Dinur , Hendler and Kogan-Sadetsky 24

Race condition for counting semaphore take 1 1. 2. 3. 4. Processes Q 1

Race condition for counting semaphore take 1 1. 2. 3. 4. Processes Q 1 – Q 4 perform down(S), Q 2 – Q 4 are preempted between lines L 1 and L 2: the value of the counting semaphore is now -3 Processes Q 5 -Q 7 now perform up(S): the value of the counting semaphore is now 0 Now, each of Q 2 -Q 4 runs in turn and perform line L 2 (down S 2) Q 2 runs but Q 3 -Q 4 block. All down( ) operations should have been “permitted”, 2 were not down(S): up(S): down(S 1); S. value--; S. value++; if(S. value < 0){ if(S. value ≤ 0) up(S 2); L 1: up(S 1); up(S 1) L 2: down(S 2); } Operating Systems, Spring 2020, Dinur , Hendler and Kogan-Sadetsky else up(S 1); 25

Implementing a counting semaphore from binary semaphores (user space): take 2 binary-semaphore S 1

Implementing a counting semaphore from binary semaphores (user space): take 2 binary-semaphore S 1 initially 1, S 2 initially 0, S. value initially 1 down(S): down(S 1); S. value--; if(S. value < 0){ up(S 1); //L 1 down(S 2); } //L 2 up(S 1); up(S): down(S 1); S. value++; if(S. value ≤ 0) up(S 2); else up(S 1) This code works, but… Operating Systems, Spring 2020, Dinur , Hendler and Kogan-Sadetsky 26

The effect of the changes up(S 1) is performed by up(S) only if no

The effect of the changes up(S 1) is performed by up(S) only if no process waits on S 2 q Q 5 leaves up(S) without releasing S 1 q Q 6 cannot enter the critical section that protects the counter q It can only do so after one of Q 2 -Q 4 releases S 1 q This generates a “lock-step” situation: an up(), a down(), an up()… q The critical section that protects the semaphore is entered alternately by producers and consumers Operating Systems, Spring 2020, Dinur , Hendler and Kogan-Sadetsky 27

Recall the bounded-buffer algorithm #define N 100 typedef int semaphore; semaphore mutex = 1;

Recall the bounded-buffer algorithm #define N 100 typedef int semaphore; semaphore mutex = 1; semaphore empty = N; semaphore full = 0; void producer(void) { producer int item; while(TRUE) { produce_item(&item); down(&empty); down(&mutex); down enter_item(item); up(&mutex); up up(&full); up } } void consumer(void) consumer { int } item; while(TRUE) { down(&full); down(&mutex); down remove_item(&item); up(&mutex); up up(&empty); up consume_item(item); } Operating Systems, Spring 2020, Dinur , Hendler and Kogan-Sadetsky 28

A problematic scheduling scenario Consider a bounded buffer of 5 slots. Assume there are

A problematic scheduling scenario Consider a bounded buffer of 5 slots. Assume there are 6 processes each filling five slots in turn. 1 2 3 4 5 6 Empty. Value = 5 Operating Systems, Spring 2020, Dinur , Hendler and Kogan-Sadetsky 29

A Problematic Scheduling Scenario 1. five slots are filled by the first producer 1

A Problematic Scheduling Scenario 1. five slots are filled by the first producer 1 2 3 4 5 6 Empty. Value = 0 Operating Systems, Spring 2020, Dinur , Hendler and Kogan-Sadetsky 30

A Problematic Scheduling Scenario 1. The second producer is blocked 1 2 3 4

A Problematic Scheduling Scenario 1. The second producer is blocked 1 2 3 4 5 6 Empty. Value = -1 Operating Systems, Spring 2020, Dinur , Hendler and Kogan-Sadetsky 31

A Problematic Scheduling Scenario 1. The third producer is blocked 1 2 3 4

A Problematic Scheduling Scenario 1. The third producer is blocked 1 2 3 4 5 6 Empty. Value = -2 Operating Systems, Spring 2020, Dinur , Hendler and Kogan-Sadetsky 32

A Problematic Scheduling Scenario 1. The fourth producer is blocked 1 2 3 4

A Problematic Scheduling Scenario 1. The fourth producer is blocked 1 2 3 4 5 6 Empty. Value = -3 Operating Systems, Spring 2020, Dinur , Hendler and Kogan-Sadetsky 33

A Problematic Scheduling Scenario 1. The fifth producer is blocked 1 2 3 4

A Problematic Scheduling Scenario 1. The fifth producer is blocked 1 2 3 4 5 6 Empty. Value = -4 Operating Systems, Spring 2020, Dinur , Hendler and Kogan-Sadetsky 34

A Problematic Scheduling Scenario 2. All blocked producers are waiting on S 2 1

A Problematic Scheduling Scenario 2. All blocked producers are waiting on S 2 1 2 3 4 5 6 Empty. Value = -5 Operating Systems, Spring 2020, Dinur , Hendler and Kogan-Sadetsky 35

A Problematic Scheduling Scenario 3. The consumer consumes an item and is blocked on

A Problematic Scheduling Scenario 3. The consumer consumes an item and is blocked on Empty. S 1 until a producer adds an item. 1 2 3 4 5 6 Empty. Value = -5 Operating Systems, Spring 2020, Dinur , Hendler and Kogan-Sadetsky 36

A Problematic Scheduling Scenario 3. The consumer consumes an item and is blocked on

A Problematic Scheduling Scenario 3. The consumer consumes an item and is blocked on S 1 , one producer adds an item. 1 2 3 4 5 6 Empty. Value = -4 Operating Systems, Spring 2020, Dinur , Hendler and Kogan-Sadetsky 37

A Problematic Scheduling Scenario 4. Consumer must consume, only then another producer wakes up

A Problematic Scheduling Scenario 4. Consumer must consume, only then another producer wakes up and produces an item 1 2 3 4 5 6 Empty. Value = -3 Operating Systems, Spring 2020, Dinur , Hendler and Kogan-Sadetsky 38

A Problematic Scheduling Scenario 4. Same as in step 3. 1 2 3 4

A Problematic Scheduling Scenario 4. Same as in step 3. 1 2 3 4 5 6 Empty. Value = -2 Operating Systems, Spring 2020, Dinur , Hendler and Kogan-Sadetsky 39

A Problematic Scheduling Scenario 5. And again… 1 2 3 4 5 6 Empty.

A Problematic Scheduling Scenario 5. And again… 1 2 3 4 5 6 Empty. Value = -1 Operating Systems, Spring 2020, Dinur , Hendler and Kogan-Sadetsky 40

Implementing a counting semaphore from binary semaphores (user space): take 3 (P. A. Kearns,

Implementing a counting semaphore from binary semaphores (user space): take 3 (P. A. Kearns, 1988) binary-semaphore S 1=1, S 2=0, value initially 1, integer wake=0 down(S) down(S 1); S. value--; if(S. value < 0){ up(S 1); //L 1 down(S 2); //L 2 down(S 1); S. wake--; if(S. wake > 0) then up(S 2); } //L 3 up(S 1); up(S): down(S 1); S. value++; if(S. value <= 0) { S. wake++; up(S 2); } up(S 1); Does THIS work? Operating Systems, Spring 2020, Dinur , Hendler and Kogan-Sadetsky 41

Correctness arguments (Kearns)… q The counter S. wake is used when processes performing down(S)

Correctness arguments (Kearns)… q The counter S. wake is used when processes performing down(S) are preempted between lines L 1 and L 2 q In such a case, up(S 2) performed by processes during up(S) has no effect q However, these processes accumulate their waking signals on the (protected) counter S. wake q After preemption is over, any single process that wakes up from its block on down(S 2) checks the value of S. wake q The check is again protected q If S. wake>0, S. wake the awakened process performs up(S 2) (in line L 3) q Each re-scheduled process wakes up the next one Operating Systems, Spring 2020, Dinur , Hendler and Kogan-Sadetsky 42

Kearns' algorithm is wrong q Processes P 0. . P 7 perform down(S), P

Kearns' algorithm is wrong q Processes P 0. . P 7 perform down(S), P 0 goes through, P 1. . P 7 go to sleep after performing line L 2 of the operation q Processes P 8. . P 11 perform up(S) and their up(S 2) operations release, say, P 1. . P 4 q Processes P 5, P 6, P 7 are still waiting on S 2 and S. wake = 4 q Processes P 1. . P 4 are ready, just before line L 3 q Each of P 1. . P 3 will decrement S. wake in its turn, check that it's positive and signal one of P 5. . P 7 q Four up operations have released 7 down operations Operating Systems, Spring 2020, Dinur , Hendler and Kogan-Sadetsky 43

Implementing a counting semaphore from binary semaphores (user space): take 4 (Hemmendinger, 1989) binary-semaphore

Implementing a counting semaphore from binary semaphores (user space): take 4 (Hemmendinger, 1989) binary-semaphore S 1=1, S 2=0, integer wake=0 down(S) down(S 1); S. value--; if(S. value < 0){ up(S 1); down(S 2); down(S 1); S. wake--; if(S. wake > 0) then up(S 2); } // L 3 up(S 1); up(S): down(S 1); S. value++; if(S. value <= 0) { S. wake++; if (S. wake == 1) up(S 2); } up(S 1); This works. Operating Systems, Spring 2020, Dinur , Hendler and Kogan-Sadetsky 44

Implementing a counting semaphore from binary semaphores (user space): take 5 (Barz, 1983) binary-semaphore

Implementing a counting semaphore from binary semaphores (user space): take 5 (Barz, 1983) binary-semaphore S 1=1, S 2=min(1, init_value), value=init_value down(S) down(S 2); down(S 1); S. value--; if (S. value>0) then up(S 2); up(S 1); up(S): down(S 1); S. value++; if(S. value == 1) { up(S 2); } up(S 1); This works, is simpler, and was published earlier(!)… Can we switch the order of downs in down(S)? Operating Systems, Spring 2020, Dinur , Hendler and Kogan-Sadetsky 45

Correctness arguments… q The critical section is guarded by S 1 and each of

Correctness arguments… q The critical section is guarded by S 1 and each of the operations down(S) and up(S) uses it to correctly update the value of S. value q After updating (and inside the critical section) both operations release the S 2 semaphore only if value is positive q S. value is never negative, because any process performing down(S) is blocked at S 2 q. Signals cannot be 'wasted' Operating Systems, Spring 2020, Dinur , Hendler and Kogan-Sadetsky 46

Fairness of semaphores q Order of releasing blocked processes: o Strong – up() performing

Fairness of semaphores q Order of releasing blocked processes: o Strong – up() performing process enters after (one of the) blocked processes o Weak – An upper bound on the number of entries of process that performed up() if others are waiting q Unfair: o No guarantee about the number of times the up() performing process enters before the blocked o Open competition each time the lock is free o Imitating the Java 'wait' /'notify' mechanism o Or the spin-lock of XV 6… Operating Systems, Spring 2020, Dinur , Hendler and Kogan-Sadetsky 47

Outline q Semaphores and the producer/consumer problem q Counting semaphores from binary semaphores q

Outline q Semaphores and the producer/consumer problem q Counting semaphores from binary semaphores q Event counters and message passing synchronization Operating Systems, Spring 2020, Dinur , Hendler and Kogan-Sadetsky 48

Event Counters q Integer counters with three operations: o Advance(E): increment E by 1,

Event Counters q Integer counters with three operations: o Advance(E): increment E by 1, wake up relevant sleepers o Await(E, v): wait until E ≥ v. Sleep if E < v o Read(E): return the current value of E q Counter value is ever increasing q The Read() operation is not required for the bounded-buffer implementation in the next slide Operating Systems, Spring 2020, Dinur , Hendler and Kogan-Sadetsky 49

producer-consumer with Event Counters (for a single producer and a single consumer) #define typedef

producer-consumer with Event Counters (for a single producer and a single consumer) #define typedef event_counter N int in = 0; out = 0; 100 event_counter; /* counts inserted items */ /* items removed from buffer */ void producer(void) { int item, sequence = 0; while(TRUE) { produce_item(&item); sequence = sequence + 1; await(out, sequence - N); enter_item(item); advance(&in); } } /* counts items produced */ /* wait for room in buffer */ /* insert into buffer */ /* inform consumer */ Operating Systems, Spring 2020, Dinur , Hendler and Kogan-Sadetsky 50

Event counters (producer-consumer) void consumer(void) { int item, sequence = 0; } while(TRUE) {

Event counters (producer-consumer) void consumer(void) { int item, sequence = 0; } while(TRUE) { sequence = sequence + 1; /* count items consumed */ await(in, sequence); /* wait for item */ remove_item(&item); /* take item from buffer */ advance(&out); /* inform producer */ consume_item(item); } Operating Systems, Spring 2020, Dinur , Hendler and Kogan-Sadetsky 51

Message Passing – no shared memory q In a multi-processor system without shared memory,

Message Passing – no shared memory q In a multi-processor system without shared memory, synchronization can be implemented by message passing q Implementation issues: o Acknowledgements may be required (messages may be lost) o Message sequence numbers required to avoid message duplication o Unique process addresses across CPUs (domains. . ) o Authentication (validate sender’s identity, a multi-machine environment…) q Two main functions: o send(destination, &message); o receive(source, &message) block while waiting. . . Operating Systems, Spring 2020, Dinur , Hendler and Kogan-Sadetsky 52

Producer-consumer using message passing void consumer(void) { int item, i; message m; for(i =

Producer-consumer using message passing void consumer(void) { int item, i; message m; for(i = 0; i < N; i++) send(producer, &m); /* send N empties */ while(TRUE) { receive(producer, &m); extract_item(&m, &item); send(producer, &m); consume_item(item); } } /* get message with item */ /* send an empty reply */ Operating Systems, Spring 2020, Dinur , Hendler and Kogan-Sadetsky 53

Producer-consumer using message passing (continued) #define N #define MSIZE 100 4 typedef int message(MSIZE);

Producer-consumer using message passing (continued) #define N #define MSIZE 100 4 typedef int message(MSIZE); void producer(void) { int item; message m; } while(TRUE) { produce_item(&item); receive(consumer, &m); construct_message(&m, item); send(consumer, &m); } /* message size */ /* message buffer */ /*wait for an empty */ /* send item */ Operating Systems, Spring 2020, Dinur , Hendler and Kogan-Sadetsky 54

Message passing variations q Messages can be addressed to a process address or to

Message passing variations q Messages can be addressed to a process address or to a mailbox o Mailboxes are generated with some capacity. When sending a message to a full mailbox, a process blocks o Buffer management done by mailbox q Unix pipes - a generalization of messages … no fixed size message (blocking receive) q If no buffer is maintained by the system, then send and receive must run in lock-step. Example: Unix rendezvous Operating Systems, Spring 2020, Dinur , Hendler and Kogan-Sadetsky 55