0% found this document useful (0 votes)
3 views

OSC___CH06___Process_Synchronization__Contd__

Chapter 6 of 'Operating System Concepts' discusses process synchronization, focusing on condition variables, semaphores, and monitors. It illustrates the implementation of pthread join() using condition variables and highlights the Producer-Consumer problem, emphasizing the importance of using while loops instead of if statements to avoid race conditions. The chapter provides code examples and explanations of synchronization mechanisms to manage concurrent processes effectively.

Uploaded by

Atsenta
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views

OSC___CH06___Process_Synchronization__Contd__

Chapter 6 of 'Operating System Concepts' discusses process synchronization, focusing on condition variables, semaphores, and monitors. It illustrates the implementation of pthread join() using condition variables and highlights the Producer-Consumer problem, emphasizing the importance of using while loops instead of if statements to avoid race conditions. The chapter provides code examples and explanations of synchronization mechanisms to manage concurrent processes effectively.

Uploaded by

Atsenta
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 42

6.CVs 7.Semaphores 8.

Monitors

OPERATING SYSTEM CONCEPTS


Chapter 6. Process Synchronization

A/Prof. Kai Dong

[email protected]
School of Computer Science and Engineering,
Southeast University

December 16, 2024

A/Prof. Kai Dong Operating System Concepts Chapter 6. Process Synchronization 1 / 42


6.CVs 7.Semaphores 8.Monitors

Contents

1 Condition Variables

2 Semaphores

3 Monitors

A/Prof. Kai Dong Operating System Concepts Chapter 6. Process Synchronization 2 / 42


6.CVs 7.Semaphores 8.Monitors

Condition Variables
Implementing pthread join()

• Two problems:
1 void ∗ c h i l d ( void ∗arg ) {
2 p i n t f ( ” c h i l d \n” ) ;
3 // Problem #1: how t o i n d i c a t e we a r e done ?
4 r e t u r n NULL ;
5 }
6
7 i n t main ( i n t a r g c , c h a r ∗ a r g v [ ] ) {
8 p r i n t f ( ” p a r e n t : b e g i n\n” ) ;
9 pthread t c ;
10 p t h r e a d c r e a t e (&c , NULL , c h i l d , NULL) ;
11 // Problem #2: how t o w a i t f o r c h i l d ?
12 p r i n t f ( ” p a r e n t : end\n” ) ;
13 return 0;
14 }

A/Prof. Kai Dong Operating System Concepts Chapter 6. Process Synchronization 3 / 42


6.CVs 7.Semaphores 8.Monitors

Condition Variables
Implementing pthread join() (contd.)

• Using a shared variable:


1 void ∗ c h i l d ( void ∗arg ) {
2 p i n t f ( ” c h i l d \n” ) ;
3 done = 1 ;
4 r e t u r n NULL ;
5 }
6
7 i n t main ( i n t a r g c , c h a r ∗ a r g v [ ] ) {
8 p r i n t f ( ” p a r e n t : b e g i n\n” ) ;
9 pthread t c ;
10 p t h r e a d c r e a t e (&c , NULL , c h i l d , NULL) ;
11 w h i l e ( done == 0 )
12 ;
13 p r i n t f ( ” p a r e n t : end\n” ) ;
14 return 0;
15 }

• Correct, but
• Waste of CPU time — spin-waiting.
• Do we need a lock here? Not a critical section.

A/Prof. Kai Dong Operating System Concepts Chapter 6. Process Synchronization 4 / 42


6.CVs 7.Semaphores 8.Monitors

Condition Variables
Implementing pthread join() (contd.)

• A condition variable is an explicit queue


• The POSIX calls:
• wait(): put itself to sleep;
• signal(): wake a sleeping thread waiting on this condition.
1 p t h r e a d c o n d w a i t ( p t h r e a d c o n d t ∗c , p t h r e a d m u t e x t ∗m) ;
2 p t h r e a d c o n d s i g n a l ( p t h r e a d c o n d t ∗c ) ;

A/Prof. Kai Dong Operating System Concepts Chapter 6. Process Synchronization 5 / 42


6.CVs 7.Semaphores 8.Monitors

Condition Variables
Implementing pthread join() (contd.)

1 i n t done = 0 ;
2 pthread mutex m =
1 void t h r j o i n () {
PTHREAD MUTEX INITIALIZER ;
2 p t h r e a d m u t e x l o c k (&m) ;
3 pthread cond t c =
3 w h i l e ( done == 0 )
PTHREAD COND INITIALIZER ;
4 p t h r e a d c o n d w a i t (&c , &m) ;
4
5 p t h r e a d m u t e x u n l o c k (&m) ;
5 void t h r e x i t () {
6 }
6 p t h r e a d m u t e x l o c k (&m) ;
7
7 done = 1 ;
8 i n t main ( i n t a r g c , c h a r ∗ a r g v [ ] ) {
8 p t h r e a d c o n d s i g n a l (& c ) ;
9 p r i n t f ( ” p a r e n t : b e g i n\n” ) ;
9 p t h r e a d m u t e x u n l o c k (&m) ;
10 pthread t p ;
10 }
11 p t h r e a d c r e a t e (&p , NULL , c h i l d , NULL) ;
11
12 t h r j o i n () ;
12 void ∗ c h i l d ( void ∗arg ) {
13 p r i n t f ( ” p a r e n t : end\n” ) ;
13 p r i n t f ( ” c h i l d \n” ) ;
14 return 0;
14 t h r e x i t () ;
15 }
15 r e t u r n NULL ;
16 }

A/Prof. Kai Dong Operating System Concepts Chapter 6. Process Synchronization 6 / 42


6.CVs 7.Semaphores 8.Monitors

Condition Variables
Implementing pthread join() (contd.)

• Condition variable is always with a lock and a flag


• Why are the following codes broken?

1 void t h r e x i t () { 1 void t h r e x i t () {
2 pthread m u t e x l o c k (&m) ; 2 done = 1 ;
3 pthread c o n d s i g n a l (& c ) ; 3 p t h r e a d c o n d s i g n a l (& c ) ;
4 pthread m u t e x u n l o c k (&m) ; 4 }
5 } 5
6 6
7 void t h r j o i n () { 7 void t h r j o i n () {
8 pthread m u t e x l o c k (&m) ; 8 i f ( done == 0 )
9 pthread c o n d w a i t (&c , &m) ; 9 p t h r e a d c o n d w a i t (& c ) ;
10 pthread m u t e x u n l o c k (&m) ; 10 }
11 } 11
12 12
13 /∗ b r o k e n c o d e #1 ∗/ 13 /∗ b r o k e n c o d e #2 ∗/

A/Prof. Kai Dong Operating System Concepts Chapter 6. Process Synchronization 7 / 42


6.CVs 7.Semaphores 8.Monitors

Condition Variables
The Producer-Consumer Problem

1 /∗ L e t ’ s b e g i n w i t h o n l y 1 p r o d u c e r , 1 consumer , b u f f e r s i z e = 1 ∗/
2
3 c o n d t cond ;
4 m u t e x t mutex
5 void ∗producer ( void ∗arg ) {
6 f o r ( i n t i = 0 ; i < l o o p s ; i ++) {
7 p t h r e a d m u t e x l o c k (&mutex ) ;
8 i f ( c o u n t == 1 )
9 p t h r e a d c o n d w a i t (&cond , &mutex ) ;
10 put ( ) ; // p r o d u c e
11 p t h r e a d c o n d s i g n a l (& cond ) ;
12 p t h r e a d m u t e x u n l o c k (&mutex ) ;
13 }
14 }
15 v o i d ∗c o n s u m e r ( v o i d ∗ a r g ) {
16 f o r ( i n t i = 0 ; i < l o o p s ; i ++) {
17 p t h r e a d m u t e x l o c k (&mutex ) ;
18 i f ( c o u n t == 0 )
19 p t h r e a d c o n d w a i t (&cond , &mutex ) ;
20 get () ; // consume
21 p t h r e a d c o n d s i g n a l (& cond ) ;
22 p t h r e a d m u t e x u n l o c k (&mutex ) ;
23 }
24 }

A/Prof. Kai Dong Operating System Concepts Chapter 6. Process Synchronization 8 / 42


6.CVs 7.Semaphores 8.Monitors

Condition Variables
The Producer-Consumer Problem (contd.)

• Problematic with more threads

Tc1 State Tc2 State Tp State Count Comment


lock Running Ready Ready 0
wait Waiting Ready Ready 0 Nothing to get
Waiting Ready lock Running 0
Waiting Ready put Running 1 Buffer now full
Ready Ready signal Running 1 Tc1 awoken
Ready Ready unlock Running 1
Ready Ready lock Running 1
Ready Ready wait Waiting 1 Buffer full
Ready lock Running Waiting 1 Tc2 sneaks in
Ready get Running Waiting 0 Tc2 grabs data
Ready signal Running Ready 0 Tp awoken
Ready unlock Running Ready 0
get Running Ready Ready 0 No data!

A/Prof. Kai Dong Operating System Concepts Chapter 6. Process Synchronization 9 / 42


6.CVs 7.Semaphores 8.Monitors

Condition Variables
The Producer-Consumer Problem (contd.)

1 /∗ S t i l l b r o k e n ∗/
2
3 c o n d t cond ;
4 m u t e x t mutex
5 void ∗producer ( void ∗arg ) {
6 f o r ( i n t i = 0 ; i < l o o p s ; i ++) {
7 p t h r e a d m u t e x l o c k (&mutex ) ;
8 w h i l e ( c o u n t == 1 ) // u s e ” w h i l e ” i n s t e a d o f ” i f ”
9 p t h r e a d c o n d w a i t (&cond , &mutex ) ;
10 put ( ) ; // p r o d u c e
11 p t h r e a d c o n d s i g n a l (& cond ) ;
12 p t h r e a d m u t e x u n l o c k (&mutex ) ;
13 }
14 }
15 v o i d ∗c o n s u m e r ( v o i d ∗ a r g ) {
16 f o r ( i n t i = 0 ; i < l o o p s ; i ++) {
17 p t h r e a d m u t e x l o c k (&mutex ) ;
18 w h i l e ( c o u n t == 0 ) // u s e ” w h i l e ” i n s t e a d o f ” i f ”
19 p t h r e a d c o n d w a i t (&cond , &mutex ) ;
20 get () ; // consume
21 p t h r e a d c o n d s i g n a l (& cond ) ;
22 p t h r e a d m u t e x u n l o c k (&mutex ) ;
23 }
24 }

A/Prof. Kai Dong Operating System Concepts Chapter 6. Process Synchronization 10 / 42


6.CVs 7.Semaphores 8.Monitors

Condition Variables
The Producer-Consumer Problem (contd.)

Tc1 State Tc2 State Tp State Count Comment


lock Running Ready Ready 0
wait Waiting Ready Ready 0 Nothing to get
Waiting lock Running Ready 0
Waiting wait Waiting Ready 0 Nothing to get
Waiting Waiting lock Running 0
Waiting Waiting put Running 1 Buffer now full
Ready Waiting signal Running 1 Tc1 awoken
Ready Waiting unlock Running 1
Ready Waiting lock Running 1
Ready Waiting wait Waiting 1 Buffer full
while Running Waiting Waiting 1 Recheck condition
get Running Waiting Waiting 0 Tc1 grabs data
signal Running Ready Waiting 0 Oops, Tc2 awoken
unlock Running Ready Waiting 0
lock Running Ready Waiting 0
wait Waiting Ready Waiting 0 Nothing to get
Waiting while Ready Waiting 0 Recheck condition
Waiting wait Waiting Waiting 0 Everyone waiting!

A/Prof. Kai Dong Operating System Concepts Chapter 6. Process Synchronization 11 / 42


6.CVs 7.Semaphores 8.Monitors

Condition Variables
The Producer-Consumer Problem (contd.)

1 /∗ b u f f e r s i z e = 1 ∗/
2
3 c o n d t empty , f i l l ; // two c o n d i t i o n v a r i a b l e s
4 m u t e x t mutex
5 void ∗producer ( void ∗arg ) {
6 f o r ( i n t i = 0 ; i < l o o p s ; i ++) {
7 p t h r e a d m u t e x l o c k (&mutex ) ;
8 w h i l e ( c o u n t == 1 )
9 p t h r e a d c o n d w a i t (&empty , &mutex ) ;
10 put ( ) ; // p r o d u c e
11 p t h r e a d c o n d s i g n a l (& f i l l ) ;
12 p t h r e a d m u t e x u n l o c k (&mutex ) ;
13 }
14 }
15 v o i d ∗c o n s u m e r ( v o i d ∗ a r g ) {
16 f o r ( i n t i = 0 ; i < l o o p s ; i ++) {
17 p t h r e a d m u t e x l o c k (&mutex ) ;
18 w h i l e ( c o u n t == 0 )
19 p t h r e a d c o n d w a i t (& f i l l , &mutex ) ;
20 get () ; // consume
21 p t h r e a d c o n d s i g n a l (&empty ) ;
22 p t h r e a d m u t e x u n l o c k (&mutex ) ;
23 }
24 }

A/Prof. Kai Dong Operating System Concepts Chapter 6. Process Synchronization 12 / 42


6.CVs 7.Semaphores 8.Monitors

Condition Variables
The Producer-Consumer Problem (contd.)

1 /∗ d e a l i n g w i t h bounded b u f f e r i n s t e a d o f s i n g l e b u f f e r ∗/
2
3 c o n d t empty , f i l l ; // s t i l l two c o n d i t i o n v a r i a b l e s
4 m u t e x t mutex
5 void ∗producer ( void ∗arg ) {
6 f o r ( i n t i = 0 ; i < l o o p s ; i ++) {
7 p t h r e a d m u t e x l o c k (&mutex ) ;
8 w h i l e ( c o u n t == MAX) // remember : a l w a y s u s e ” w h i l e ”
9 p t h r e a d c o n d w a i t (&empty , &mutex ) ;
10 put ( ) ; // p r o d u c e
11 p t h r e a d c o n d s i g n a l (& f i l l ) ;
12 p t h r e a d m u t e x u n l o c k (&mutex ) ;
13 }
14 }
15 v o i d ∗c o n s u m e r ( v o i d ∗ a r g ) {
16 f o r ( i n t i = 0 ; i < l o o p s ; i ++) {
17 p t h r e a d m u t e x l o c k (&mutex ) ;
18 w h i l e ( c o u n t == 0 )
19 p t h r e a d c o n d w a i t (& f i l l , &mutex ) ;
20 get () ; // consume
21 p t h r e a d c o n d s i g n a l (&empty ) ;
22 p t h r e a d m u t e x u n l o c k (&mutex ) ;
23 }
24 }

A/Prof. Kai Dong Operating System Concepts Chapter 6. Process Synchronization 13 / 42


6.CVs 7.Semaphores 8.Monitors

Condition Variables
Covering Condition

• Consider a memory allocation scenario:


• Assume there are 0 bytes free;
• Thread Ta calls allocate(100)
• Thread Tb calls allocate(10)
• Thread Tc calls free(50)
• Which thread to signal?
• What if Ta is awoken?
• pthread cond broadcast(), to wake up all waiting threads.

A/Prof. Kai Dong Operating System Concepts Chapter 6. Process Synchronization 14 / 42


6.CVs 7.Semaphores 8.Monitors

Contents

1 Condition Variables

2 Semaphores

3 Monitors

A/Prof. Kai Dong Operating System Concepts Chapter 6. Process Synchronization 15 / 42


6.CVs 7.Semaphores 8.Monitors

Semaphores

• A semaphore is an object with an integer value that we can manipulate with two
routines: wait() and signal().
• In the POSIX standard, these routines are sem wait() and sem post().
• Historically, Dijkstra uses P() and V (). P() comes from “prolaag”, a
contraction of “probeer” (Dutch for “try”) and “verlaag” (“decrease”);
V () comes from the Dutch word “verhoog” which means “increase”.

1 // C o r r e c t ! 1 // I n c o r r e c t !
2 wait ( s ) { 2 wait ( s ) {
3 w h i l e ( s <= 0 ) ; // S p i n ! 3 s −−;
4 s −−; 4 w h i l e ( s < 0) ;
5 } 5 }
6 6
7 signal (s) { 7 signal (s) {
8 s ++; 8 s ++;
9 } 9 }

A/Prof. Kai Dong Operating System Concepts Chapter 6. Process Synchronization 16 / 42


6.CVs 7.Semaphores 8.Monitors

Semaphores
Semaphore Implementation

• To overcome the need for busy waiting:


1 typedef struct {
2 int value ;
3 struct process ∗ l i s t ;
4 } semaphore ;
5
6 w ait ( semaphore ∗s ) {
7 s−>v a l u e −−;
8 i f ( s−>v a l u e < 0 ) {
9 add t h i s p r o c e s s t o s−>l i s t ;
10 block () ;
11 }
12 }
13
14 s i g n a l ( semaphore ∗s ) {
15 s−>v a l u e ++;
16 i f ( s−>v a l u e <= 0 ) {
17 remove a p r o c e s s P from s−>l i s t ;
18 wakeup (P) ;
19 }
20 }

A/Prof. Kai Dong Operating System Concepts Chapter 6. Process Synchronization 17 / 42


6.CVs 7.Semaphores 8.Monitors

Semaphores
Why Semaphores

Semaphore = Mutex + Integer + ConditionVariable

• Functionality
• A single primitive for all things related to synchronization
• Both locks and condition variables
• Correctness and Convenience
• Avoid errors — can signal() first then wait().
• Clean and organized — making it easy to demonstrate their correctness.
• Efficient.

A/Prof. Kai Dong Operating System Concepts Chapter 6. Process Synchronization 18 / 42


6.CVs 7.Semaphores 8.Monitors

Semaphores
Basic Synchronization Patterns

• Signaling
• Rendezvous
• Mutex
• Multiplex
• Barrier
• Reusable barrier
• Pairing

A/Prof. Kai Dong Operating System Concepts Chapter 6. Process Synchronization 19 / 42


6.CVs 7.Semaphores 8.Monitors

Semaphores
Signaling

1 /∗ Thread A ∗/ 1 /∗ Thread B ∗/
2 statement a ; 2 statement b ;

• How to guarantee that a happens before b?

1 /∗ Thread A ∗/ 1 /∗ Thread B ∗/
2 statement a ; 2 wait ( s ) ;
3 signal (s) ; 3 statement b ;

• What should semaphore s initially be?

A/Prof. Kai Dong Operating System Concepts Chapter 6. Process Synchronization 20 / 42


6.CVs 7.Semaphores 8.Monitors

Semaphores
Rendezvous

1 /∗ Thread A ∗/ 1 /∗ Thread B ∗/
2 s t a t e m e n t a1 ; 2 s t a t e m e n t b1 ;
3 s t a t e m e n t a2 ; 3 s t a t e m e n t b2 ;

• How to guarantee that a1 happens before b2, and b1 before a2?

1 /∗ Thread A ∗/ 1 /∗ Thread B ∗/
2 s t a t e m e n t a1 ; 2 s t a t e m e n t b1 ;
3 signal (a) ; 3 signal (b) ;
4 wait (b) ; 4 wait ( a) ;
5 s t a t e m e n t a2 ; 5 s t a t e m e n t b2 ;

• What should semaphores a, b initially be?

A/Prof. Kai Dong Operating System Concepts Chapter 6. Process Synchronization 21 / 42


6.CVs 7.Semaphores 8.Monitors

Semaphores
Rendezvous (contd.)

• Is it correct? — Yes, but probably less efficient.


1 /∗ Thread A ∗/ 1 /∗ Thread B ∗/
2 s t a t e m e n t a1 ; 2 s t a t e m e n t b1 ;
3 signal (a) ; 3 wait ( a) ;
4 wait (b) ; 4 signal (b) ;
5 s t a t e m e n t a2 ; 5 s t a t e m e n t b2 ;

• Is it correct? — No, deadlock.

1 /∗ Thread A ∗/ 1 /∗ Thread B ∗/
2 s t a t e m e n t a1 ; 2 s t a t e m e n t b1 ;
3 wait (b) ; 3 wait ( a) ;
4 signal (a) ; 4 signal (b) ;
5 s t a t e m e n t a2 ; 5 s t a t e m e n t b2 ;

A/Prof. Kai Dong Operating System Concepts Chapter 6. Process Synchronization 22 / 42


6.CVs 7.Semaphores 8.Monitors

Semaphores
Mutex

1 /∗ Thread A ∗/ 1 /∗ Thread B ∗/
2 count = count + 1; 2 count = count + 1;

• Add semaphores to the following example to enforce mutual exclusion to the


shared variable count.
1 /∗ Thread A ∗/ 1 /∗ Thread B ∗/
2 w a i t ( mutex ) ; 2 w a i t ( mutex ) ;
3 count = count + 1; 3 count = count + 1;
4 s i g n a l ( mutex ) ; 4 s i g n a l ( mutex ) ;

• What should semaphores mutex initially be?

A/Prof. Kai Dong Operating System Concepts Chapter 6. Process Synchronization 23 / 42


6.CVs 7.Semaphores 8.Monitors

Semaphores
Multiplex

• Generalize the previous solution so that it allows multiple threads to run in the
critical section at the same time, but it enforces an upper limit (MAX ) on the
number of concurrent threads.
1 wait ( multiplex ) ;
2 count = count + 1; // c r i t i c a l section
3 signal ( multiplex ) ;

• What should semaphores multiplex initially be?

A/Prof. Kai Dong Operating System Concepts Chapter 6. Process Synchronization 24 / 42


6.CVs 7.Semaphores 8.Monitors

Semaphores
Barrier

• Generalize the rendezvous solution. n threads should run the following code:
1 rendezvous ;
2 c r i t i c a l point ;

• How to ensure that no thread executes critical point until after all threads have
executed rendezvous?
1 rendezvous ;
2 w a i t ( mutex ) ;
3 count = count + 1;
1 /∗ i n i t i a l i z a t i o n ∗/
4 s i g n a l ( mutex ) ;
2 i n t count = 0;
5 i f ( c o u n t == n )
3 s e m a p h o r e mutex = 1 ;
6 signal ( barrier ) ;
4 semaphore b a r r i e r = 0 ;
7 wait ( b a r r i e r ) ;
8 signal ( barrier ) ;
9 c r i t i c a l point ;

A/Prof. Kai Dong Operating System Concepts Chapter 6. Process Synchronization 25 / 42


6.CVs 7.Semaphores 8.Monitors

Semaphores
Barrier (contd.)

1 /∗ Bad b a r r i e r s o l u t i o n ∗/
2 rendezvous ;
3 w a i t ( mutex ) ;
4 count = count + 1;
5 i f ( c o u n t == n )
6 signal ( barrier ) ;
7 wait ( b a r r i e r ) ;
8 signal ( barrier ) ;
9 s i g n a l ( mutex ) ;
10 c r i t i c a l point ;

• Common source of deadlocks: blocking on a semaphore while holding a mutex.

A/Prof. Kai Dong Operating System Concepts Chapter 6. Process Synchronization 26 / 42


6.CVs 7.Semaphores 8.Monitors

Semaphores
Reusable Barrier (contd.)

1 s e m a p h o r e b a r r i e r 1 = 0 , b a r r i e r 2 = 0 , mutex = 1 ;
2
3 rendezvous ;
4 w a i t ( mutex ) ;
5 c o u n t += 1 ;
6 i f ( c o u n t == n )
7 for ( int i = 0 ; i < n ; i ++)
8 signal ( barrier1 ) ;
9 s i g n a l ( mutex ) ;
10 wait ( b a r r i e r 1 ) ;
11 c r i t i c a l point ;
12 w a i t ( mutex ) ;
13 c o u n t −= 1 ;
14 i f ( c o u n t == 0 )
15 for ( int i = 0 ; i < n ; i ++)
16 signal ( barrier2 ) ;
17 s i g n a l ( mutex ) ;
18 wait ( b a r r i e r 2 ) ;

A/Prof. Kai Dong Operating System Concepts Chapter 6. Process Synchronization 27 / 42


6.CVs 7.Semaphores 8.Monitors

Semaphores
Pairing

• Imagine that threads represent ballroom dancers and that two kinds of dancers,
leaders and followers, wait in two queues before entering the dance floor. When
a leader arrives, it checks to see if there is a follower waiting. If so, they can
both proceed. Otherwise it waits. Similarly, when a follower arrives, it checks for
a leader and either proceeds or waits, accordingly.
1 semaphore l e a d e r = 0 , f o l l o w e r = 0 ;

1 /∗ l e a d e r ∗/ 1 /∗ f o l l o w e r ∗/
2 signal ( leader ) ; 2 signal ( follower ) ;
3 wait ( f o l l o w e r ) ; 3 wait ( leader ) ;
4 dance ( ) ; 4 dance ( ) ;

• How to ensure dance() are executed in pairs?

A/Prof. Kai Dong Operating System Concepts Chapter 6. Process Synchronization 28 / 42


6.CVs 7.Semaphores 8.Monitors

Semaphores
Pairing (contd.)

1 /∗ i n i t i a l i z a t i o n ∗/
2 i n t n u m l = 0 , num f = 0 ;
3 s e m a p h o r e l e a d e r = 0 , f o l l o w e r = 0 , p a i r i n g = 0 , mutex = 1 ;

1 /∗ l e a d e r ∗/ 1 /∗ f o l l o w e r ∗/
2 w a i t ( mutex ) ; 2 w a i t ( mutex ) ;
3 i f ( num f > 0 ) { 3 i f ( num l > 0) {
4 num f −−; 4 n u m l −−;
5 signal ( leader ) ; 5 signal ( follower ) ;
6 } 6 }
7 else { 7 else {
8 n u m l ++; 8 num f ++;
9 s i g n a l ( mutex ) ; 9 s i g n a l ( mutex ) ;
10 wait ( f o l l o w e r ) ; 10 wait ( leader ) ;
11 } 11 }
12 dance ( ) ; 12 dance ( ) ;
13 wait ( p a i r i n g ) ; 13 signal ( pairing ) ;
14 s i g n a l ( mutex ) ; 14 // no s i g n a l ( mutex ) ;

A/Prof. Kai Dong Operating System Concepts Chapter 6. Process Synchronization 29 / 42


6.CVs 7.Semaphores 8.Monitors

Semaphore
The Producer-Consumer Problem

1 s e m a p h o r e empty = MAX, f u l l = 0 , mutex = 1 ;


2
3 void ∗producer ( void ∗args ) {
4 for ( int i = 0; i < loops ; i ++) {
5 w a i t ( empty ) ;
6 w a i t ( mutex ) ;
7 put ( ) ;
8 s i g n a l ( mutex ) ;
9 signal ( full ) ;
10 }
11 }
12
13 v o i d ∗c o n s u m e r ( v o i d ∗ a r g s ) {
14 for ( int i = 0; i < loops ; i ++) {
15 wait ( f u l l ) ;
16 w a i t ( mutex ) ;
17 get () ;
18 s i g n a l ( mutex ) ;
19 s i g n a l ( empty ) ;
20 }
21 }

A/Prof. Kai Dong Operating System Concepts Chapter 6. Process Synchronization 30 / 42


6.CVs 7.Semaphores 8.Monitors

Semaphore
The Dining Philosophers

• There are five “philosophers” sitting around a table. Between each pair of
philosophers is a single chopstick (and thus, five total). The philosophers each
have times where they think, and don’t need any chopsticks, and times where
they eat. In order to eat, a philosopher needs two chopsticks, both the one on
their left and the one on their right. The basic loop of each philosopher is as
follows, assuming each has a unique identifier p ∈ [0, 4]:
1 while ( true ) {
2 think () ;
3 getchopsticks () ;
4 eat () ;
5 putchopsticks () ;
6 }

A/Prof. Kai Dong Operating System Concepts Chapter 6. Process Synchronization 31 / 42


6.CVs 7.Semaphores 8.Monitors

Semaphore
The Dining Philosophers (contd.)

1 /∗ a f a i l e d s o l u t i o n , why f a i l e d ? ∗/
2
3 int l e f t ( int p) { return p ; }
4 int r i g h t ( i n t p ) {r e t u r n ( p + 1) % 5 ; }
5
6 void putchopsticks () {
7 signal ( chopsticks [ l e f t (p) ]) ;
8 signal ( chopsticks [ right (p) ]) ;
9 }
10
11 void getchopsticks () {
12 wait ( chopsticks [ l e f t (p) ] ) ;
13 wait ( chopsticks [ r i g h t (p) ] ) ;
14 }

A/Prof. Kai Dong Operating System Concepts Chapter 6. Process Synchronization 32 / 42


6.CVs 7.Semaphores 8.Monitors

Semaphore
The Dining Philosophers (contd.)

1 /∗ a c o r r e c t s o l u t i o n ∗/
2
3 int l e f t ( int p) { return p ; }
4 int r i g h t ( i n t p ) {r e t u r n ( p + 1) % 5 ; }
5
6 void putchopsticks () {
7 signal ( chopsticks [ l e f t (p) ]) ;
8 signal ( chopsticks [ right (p) ]) ;
9 }
10
11 void getchopsticks () {
12 i f ( p == 4 ) {
13 wait ( chopsticks [ right (p) ]) ;
14 wait ( chopsticks [ l e f t (p) ]) ;
15 }
16 else {
17 wait ( chopsticks [ l e f t (p) ]) ;
18 wait ( chopsticks [ right (p) ]) ;
19 }
20 }

A/Prof. Kai Dong Operating System Concepts Chapter 6. Process Synchronization 33 / 42


6.CVs 7.Semaphores 8.Monitors

Semaphore
The Readers-Writers Problem

• Imagine a number of concurrent operations, including reads and writes.


• Writes change the state of the data
• Reads do not — Many reads can proceed concurrently, as long as we can
guarantee that no write is on-going.
• The first readers–writers problem — requires that, no reader be kept waiting
unless a writer has already obtained permission to use the shared object.
• The second readers-writers problem — requires that, once a writer is ready, that
writer perform its write as soon as possible.

A/Prof. Kai Dong Operating System Concepts Chapter 6. Process Synchronization 34 / 42


6.CVs 7.Semaphores 8.Monitors

Semaphore
The First Readers-Writers Problem

1 semaphore w r i t e m u t e x = 1 ;
2 semaphore readcount mutex = 1 ;
3 int read count = 0;

1 void read () {
2 do {
3 wait ( readcount mutex ) ;
4 r e a d c o u n t ++;
1 void write () { 5 i f ( r e a d c o u n t == 1 )
2 do { 6 wait ( write mutex ) ;
3 wait ( write mutex ) ; 7 s i g n a l ( readcount mutex ) ;
4 /∗ w r i t i n g ∗/ 8 /∗ r e a d i n g ∗/
5 s i g n a l ( write mutex ) ; 9 wait ( readcount mutex ) ;
6 } 10 r e a d c o u n t −−;
7 while ( true ) ; 11 i f ( r e a d c o u n t == 0 )
8 } 12 s i g n a l ( write mutex ) ;
13 s i g n a l ( readcount mutex ) ;
14 }
15 while ( true ) ;
16 }

A/Prof. Kai Dong Operating System Concepts Chapter 6. Process Synchronization 35 / 42


6.CVs 7.Semaphores 8.Monitors

Semaphore
The No-starve Readers-Writers Problem

1 s e m a p h o r e r e a d c o u n t m u t e x= 1 ;
2 s e m a p h o r e w r i t e m u t e x =1;
3 int read count = 0;
4 s e m a p h o r e r e a d m u t e x =1;

1 void read () {
2 do {
3 wait ( readmutex ) ;
4 s i g n a l ( readmutex ) ;
1 void write () { 5 wait ( readcount mutex ) ;
2 do { 6 r e a d c o u n t ++;
3 wait ( readmutex ) ; 7 i f ( r e a d c o u n t == 1 )
4 wait ( writemutex ) ; 8 wait ( writemutex ) ;
5 /∗ w r i t i n g ∗/ 9 s i g n a l ( readcount mutex ) ;
6 s i g n a l ( writemutex ) ; 10 /∗ r e a d i n g ∗/
7 s i g n a l ( readmutex ) ; 11 wait ( readcount mutex ) ;
8 } 12 r e a d c o u n t −−;
9 while ( true ) ; 13 i f ( r e a d c o u n t == 0 )
10 } 14 s i g n a l ( writemutex ) ;
15 s i g n a l ( readcount mutex ) ;
16 }
17 while ( true ) ;
18 }

A/Prof. Kai Dong Operating System Concepts Chapter 6. Process Synchronization 36 / 42


6.CVs 7.Semaphores 8.Monitors

Semaphore
The Second Readers-Writers Problem

1 semaphore r e a d c o u n t m u t e x= 1 ;
2 semaphore w r i t e m u t e x =1;
3 int write count = read count = 0;
4 semaphore w r i t e c o u n t m u t e x= 1 ;
5 semaphore r e a d m u t e x =1;

1 void write () { 1 void read () {


2 do { 2 do {
3 wait ( writecount mutex ) ; 3 wait ( readmutex ) ;
4 w r i t e c o u n t ++; 4 wait ( readcount mutex ) ;
5 i f ( w r i t e c o u n t == 1 ) 5 r e a d c o u n t ++;
6 wait ( readmutex ) ; 6 i f ( r e a d c o u n t == 1 )
7 s i g n a l ( writecount mutex ) ; 7 wait ( writemutex ) ;
8 wait ( writemutex ) ; 8 s i g n a l ( readcount mutex ) ;
9 /∗ w r i t i n g ∗/ 9 s i g n a l ( readmutex ) ;
10 s i g n a l ( writemutex ) ; 10 /∗ r e a d i n g ∗/
11 wait ( writecount mutex ) ; 11 wait ( readcount mutex ) ;
12 w r i t e c o u n t −−; 12 r e a d c o u n t −−;
13 i f ( w r i t e c o u n t == 0 ) 13 i f ( r e a d c o u n t == 0 )
14 s i g n a l ( readmutex ) ; 14 s i g n a l ( writemutex ) ;
15 s i g n a l ( writecount mutex ) ; 15 s i g n a l ( readcount mutex ) ;
16 } 16 }
17 while ( true ) ; 17 while ( true ) ;
18 } 18 }

A/Prof. Kai Dong Operating System Concepts Chapter 6. Process Synchronization 37 / 42


6.CVs 7.Semaphores 8.Monitors

Semaphores
Why and Why Not Semaphores

• Why semaphores?
• Avoid errors/Clean and organized/Efficient.
• Synchronization between Processes.
• How about performance? Better than you can imagine.
• Why not semaphores?
• Signaling all (broadcast) in CV.
• Priority inheritance in mutex locks.

A/Prof. Kai Dong Operating System Concepts Chapter 6. Process Synchronization 38 / 42


6.CVs 7.Semaphores 8.Monitors

Contents

1 Condition Variables

2 Semaphores

3 Monitors

A/Prof. Kai Dong Operating System Concepts Chapter 6. Process Synchronization 39 / 42


6.CVs 7.Semaphores 8.Monitors

Monitors

• Why monitors?
• As object-oriented programming was gaining ground, people started to
think about ways to merge synchronization into a more structured
programming environment.
• With a monitor class — the monitor guarantees that only one thread can be
active within the monitor at a time.
• A Java Monitor — add the keyword synchronized to the method or set of
methods that you wish to use as a monitor
1 public c l a s s SynchronizaedCounter {
2 private int c = 0;
3 public synchronized void increment () {
4 c ++;
5 }
6 p u b l i c s y n c h r o n i z e d void decrement () {
7 c −−;
8 }
9 public synchronized int value () {
10 return c ;
11 }
12 }

A/Prof. Kai Dong Operating System Concepts Chapter 6. Process Synchronization 40 / 42


6.CVs 7.Semaphores 8.Monitors

Monitors
Hoare Vs. Mesa

• Hoare Semantics:
• The signal() immediately wakes one waiting thread.
• Guess which one is more popular?
• Mesa semantics:
• The signal() move a single waiting thread to ready state.

A/Prof. Kai Dong Operating System Concepts Chapter 6. Process Synchronization 41 / 42


6.CVs 7.Semaphores 8.Monitors

Monitors
Hoare Vs. Mesa (contd.)

1 /∗ c o r r e c t w i t h Hoare s e m a n t i c , b u t i n c o r r e c t w i t h Mesa s e m a n t i c ∗/
2 monitor c l a s s BoundedBuffer {
3 p r i v a t e : i n t b u f f e r [MAX ] ;
4 i n t f i l l , use , f u l l E n t i r e s = 0 ;
5 c o n d t empty , f u l l ;
6 p u b l i c : void produce ( i n t element ) {
7 i f ( f u l l E n t i r e s == MAX)
8 // c o r r e c t w i t h Mesa c h a n g i n g ” i f ” t o ” w h i l e ”
9 w a i t (&empty ) ;
10 b u f f e r [ f i l l ] = element ;
11 f i l l = ( f i l l + 1 ) % MAX;
12 f u l l E n t r i e s ++;
13 s i g n a l (& f u l l ) ;
14 }
15 i n t consume ( ) {
16 i f ( f u l l E n t r i e s == 0 )
17 // c o r r e c t w i t h Mesa c h a n g i n g ” i f ” t o ” w h i l e ”
18 w a i t (& f u l l ) ;
19 i n t tmp = b u f f e r [ u s e ] ;
20 u s e = ( u s e + 1 ) % MAX;
21 f u l l E n t r i e s −−;
22 s i g n a l (&empty ) ;
23 r e t u r n tmp ;
24 }
25 }

A/Prof. Kai Dong Operating System Concepts Chapter 6. Process Synchronization 42 / 42

You might also like