CH5 - Process Synchronization 
The Critical-Section Problem 
有些資源只能同時被一個 process 使用。
1
 2
 3
 4
 5
 6
  
do  { 
    entry_section (); 
     // critical section
  exit_section (); 
    // remainder section
  while  ( true ); 
 
 
Mutual Excusion 
Progress (Freedom from Deadlock) 
Bounded Wait (Freedom from Starvation) 
 
preemptive: 資源被使用時可以被打斷 
non-preemptive 
 
Peterson’s Solution 
 1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
  
class  PetersonLock  { 
    // shared var.
  bool  flag [ 2 ]; 
    int  victim ; 
   public : 
     void  lock ()  { 
         int  i  =  ThreadID . get (); 
         int  j  =  1  -  i ; 
         flag [ i ]  =  true ; 
         victim  =  i ; 
         while  ( flag [ j ]  &&  victim  ==  i ); 
     } 
     void  unlock ()  { 
         int  i  =  ThreadID . get (); 
         flag [ i ]  =  false ; 
     } 
 }; 
 
 
1
 2
 3
 4
 5
 6
  
do  { 
    lock (); 
     // critical section
  unlock (); 
    // remainder section
  while  ( true ); 
 
 
Test & Set 
1
 2
 3
 4
 5
 6
  
// atomic
 bool  test_and_set  ( bool  * target )  { 
    bool  ret  =  * target ; 
     * taget  =  true ; 
     return  ret ; 
 } 
 
 
 1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
  
do  { 
    wait [ i ]  =  true ; 
     while  ( wait [ i ]  &&  test_and_set ( & lock )  ); 
     wait [ i ]  =  false ; 
     // critical section
  j  =  ( i  +  1 )  %  n ; 
    while  (  ( j  !=  i )  &&  ! waiting [ j ]  ) 
         j  =  ( j  +  1 )  %  n ; 
     if  ( j  ==  i ) 
         lock  =  flase ; 
     else 
         wait [ j ]  =  false ; 
 }  while  ( true ); 
 
 
Compare & Swap 
1
 2
 3
 4
 5
 6
  
int  compare_and_swap  ( int  *  val ,  int  expected ,  int  new_val )  { 
    int  tmp  =  * val ; 
     if  ( * val  ==  expected ) 
         * val  =  new_value ; 
     return  tmp ; 
 } 
 
 
1
 2
 3
 4
 5
 6
  
do  { 
    while  ( compare_and_swap ( & lock ,  0 ,  1 )  ); 
     // critical section
  lock  =  0 ; 
    // remainder section
  }  while  ( true ); 
 
 
Mutex 
acqueire() and release() are atomic.
 1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
  
acquire ()  { 
    while  ( ! available )  ; 
     available  =  false ; 
 } 
release  ()  { 
    available  =  true ; 
 } 
 do  { 
    acquire (); 
     // critical section
  release (); 
    // remainder section
  }  while  ( true ); 
 
 
Semaphore 
counting/binary semaphore 
semaphore S : integer 
wait() and signal() are atomic 
1
 2
 3
 4
 5
 6
 7
 8
  
wait ( S )  { 
    while  ( S  <=  0 ) 
         yeild (); 
     S -- ; 
 } 
signal ( S )  { 
    S ++ ; 
 }     
 
 
Implementation (Blocking) 
 1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
  
struct  sempaphore  { 
    int  cnt ; 
     queue  q ; 
 } 
 void  wait ( semaphore  * S )  { 
    S -> cnt -- ; 
     if  ( S -> cnt  <  0 )  { 
         S -> q . push ( process ); 
         block (); 
     } 
 } 
 void  signal ( semaphore  * S )  { 
    S -> cnt ++ ; 
     if  ( S -> cnt  >=  0 )  { 
         P  =  S -> q . pop (); 
         wakeup ( P ); 
     } 
 } 
 
 
Examples 
1. Bounded-Buffer Problem 
1
 2
 3
 4
  
init Semaphores:
     mutex->cnt = 1;
     full->cnt = 0;
     empty->cnt = N;
  
 
 1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
  
// producer
 do  { 
    // produce an item
  wait ( empty ); 
    wait ( mutex ); 
     // add the item to buffer;
  buffer [ in ]  =  product ; 
    in  =  ( in  +  1 )  %  N ; 
     signal ( mutex ); 
     signal ( full ); 
 }  while  ( true );     
 
 
 1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
  
// consumer
 do  { 
    // produce an item
  wait ( full ); 
    wait ( mutex ); 
     // add the item to buffer;
  product  =  buffer [ out ]; 
    out  =  ( out  +  1 )  %  N ; 
     signal ( mutex ); 
     signal ( empty ); 
 }  while  ( true );  
 
 
2. Readers-Writers Problem 
3. Dining-Philosophers Problem 
 
    
    
    
    
    
        
   
        Licensed under CC BY-NC-ND