Karşılıklı Dışlama için Peterson Algoritması | Set 1 (Temel C uygulaması)

Sorun: i ve j gibi 2 süreç göz önüne alındığında, herhangi bir ek donanım desteği olmadan ikisi arasında karşılıklı dışlamayı garanti edebilecek bir program yazmanız gerekir.

Çözüm: Bu sorunu çözmenin birden fazla yolu olabilir ancak bunların çoğu ek donanım desteği gerektirir. Bunu yapmanın en basit ve en popüler yolu karşılıklı Dışlama için Peterson Algoritmasını kullanmaktır. 1981 yılında Peterson tarafından geliştirildi, ancak bu yöndeki ilk çalışma Theodorus Jozef Dekker tarafından yapıldı. KAPAK ALGORİTMASI 1960 yılında daha sonra Peterson tarafından geliştirildi ve şu şekilde bilinmeye başlandı: Peterson Algoritması .

Temel olarak Peterson'ın algoritması yalnızca paylaşılan belleği kullanarak garantili karşılıklı dışlama sağlar. Algoritmada iki fikir kullanır:

  1. Kilit kazanma isteği.
  2. Kilidi almak için çevirin.

Önkoşul: C'de çoklu iş parçacığı

Açıklama : Buradaki fikir, önce bir ipliğin bir kilit alma arzusunu ifade etmesi ve bayrak[kendisi] = 1 ve sonra diğer iş parçacığına kilidi alma şansı verir. İplik kilidi almak isterse kilidi alır ve şansı 1. ipliğe geçirir. Kilidi almak istemiyorsa while döngüsü kırılır ve 1. iş parçacığı şansı yakalar.

Aşağıdaki kod uygulaması POSIX iş parçacıklarını kullanır ( pthread ) C programlarında ve alt düzey sistem programlamada yaygındır ancak daha fazla manuel çalışma ve tipleme gerektirir.

C++
   #include          #include         using     namespace     std  ;   int     flag  [  2  ];   int     turn  ;   const     int     MAX     =     1e9  ;   int     ans     =     0  ;   void     lock_init  ()   {      flag  [  0  ]     =     flag  [  1  ]     =     0  ;      turn     =     0  ;   }   void     lock  (  int     self  )   {      flag  [  self  ]     =     1  ;      turn     =     1     -     self  ;      while     (  flag  [  1     -     self  ]     ==     1     &&     turn     ==     1     -     self  );   }   void     unlock  (  int     self  )   {      flag  [  self  ]     =     0  ;   }   void  *     func  (  void  *     s  )   {      int     i     =     0  ;      int     self     =     (  int  )  s  ;      cout      < <     'Thread Entered: '      < <     self      < <     endl  ;      lock  (  self  );      for     (  i     =     0  ;     i      <     MAX  ;     i  ++  )      ans  ++  ;      unlock  (  self  );      return     nullptr  ;   }   int     main  ()   {      pthread_t     p1       p2  ;      lock_init  ();      pthread_create  (  &  p1       nullptr       func       (  void  *  )  0  );      pthread_create  (  &  p2       nullptr       func       (  void  *  )  1  );      pthread_join  (  p1       nullptr  );      pthread_join  (  p2       nullptr  );      cout      < <     'Actual Count: '      < <     ans      < <     ' | Expected Count: '      < <     MAX     *     2      < <     endl  ;      return     0  ;   
C
   // mythread.h (A wrapper header file with assert   // statements)   #ifndef __MYTHREADS_h__   #define __MYTHREADS_h__   #include         #include          #include         void     Pthread_mutex_lock  (  pthread_mutex_t     *  m  )   {      int     rc     =     pthread_mutex_lock  (  m  );      assert  (  rc     ==     0  );   }       void     Pthread_mutex_unlock  (  pthread_mutex_t     *  m  )   {      int     rc     =     pthread_mutex_unlock  (  m  );      assert  (  rc     ==     0  );   }       void     Pthread_create  (  pthread_t     *  thread       const     pthread_attr_t     *  attr           void     *  (  *  start_routine  )(  void  *  )     void     *  arg  )   {      int     rc     =     pthread_create  (  thread       attr       start_routine       arg  );      assert  (  rc     ==     0  );   }   void     Pthread_join  (  pthread_t     thread       void     **  value_ptr  )   {      int     rc     =     pthread_join  (  thread       value_ptr  );      assert  (  rc     ==     0  );   }   #endif   // __MYTHREADS_h__   
Java
   import     java.util.concurrent.locks.Lock  ;   import     java.util.concurrent.locks.ReentrantLock  ;   public     class   PetersonSpinlockThread     {      // Shared variables for mutual exclusion      private     static     int  []     flag     =     new     int  [  2  ]  ;      private     static     int     turn  ;      private     static     final     int     MAX     =     (  int  )     1e9  ;      private     static     int     ans     =     0  ;      private     static     Lock     mutex     =     new     ReentrantLock  ();      // Initialize lock variables      private     static     void     lockInit  ()     {      flag  [  0  ]     =     flag  [  1  ]     =     0  ;      turn     =     0  ;      }      // Acquire lock      private     static     void     lock  (  int     self  )     {      flag  [  self  ]     =     1  ;      turn     =     1     -     self  ;      // Spin until the other thread releases the lock      while     (  flag  [  1     -     self  ]     ==     1     &&     turn     ==     1     -     self  );      }      // Release lock      private     static     void     unlock  (  int     self  )     {      flag  [  self  ]     =     0  ;      }      // Function representing the critical section      private     static     void     func  (  int     self  )     {      int     i     =     0  ;      System  .  out  .  println  (  'Thread Entered: '     +     self  );      lock  (  self  );     // Acquire the lock      for     (  i     =     0  ;     i      <     MAX  ;     i  ++  )      ans  ++  ;      unlock  (  self  );     // Release the lock      }      // Main method      public     static     void     main  (  String  []     args  )     throws     InterruptedException     {      // Create two threads      Thread     t1     =     new     Thread  (()     ->     func  (  0  ));      Thread     t2     =     new     Thread  (()     ->     func  (  1  ));      lockInit  ();     // Initialize lock variables      t1  .  start  ();     // Start thread 1      t2  .  start  ();     // Start thread 2      t1  .  join  ();     // Wait for thread 1 to finish      t2  .  join  ();     // Wait for thread 2 to finish      // Print the final count      System  .  out  .  println  (  'Actual Count: '     +     ans     +     ' | Expected Count: '     +     MAX     *     2  );      }   }   
Python
   import   threading   # Shared variables for mutual exclusion   flag   =   [  0     0  ]   turn   =   0   MAX   =   int  (  1e9  )   ans   =   0   mutex   =   threading  .  Lock  ()   # Initialize lock variables   def   lock_init  ():   global   flag     turn   flag   =   [  0     0  ]   turn   =   0   # Acquire lock   def   lock  (  self  ):   global   flag     turn   flag  [  self  ]   =   1   turn   =   1   -   self   # Spin until the other thread releases the lock   while   flag  [  1   -   self  ]   ==   1   and   turn   ==   1   -   self  :   pass   # Release lock   def   unlock  (  self  ):   global   flag   flag  [  self  ]   =   0   # Function representing the critical section   def   func  (  self  ):   global   ans   i   =   0   print  (  f  'Thread Entered:   {  self  }  '  )   with   mutex  :   lock  (  self  )   # Acquire the lock   for   i   in   range  (  MAX  ):   ans   +=   1   unlock  (  self  )   # Release the lock   # Main method   def   main  ():   # Create two threads   t1   =   threading  .  Thread  (  target  =  lambda  :   func  (  0  ))   t2   =   threading  .  Thread  (  target  =  lambda  :   func  (  1  ))   lock_init  ()   # Initialize lock variables   t1  .  start  ()   # Start thread 1   t2  .  start  ()   # Start thread 2   t1  .  join  ()   # Wait for thread 1 to finish   t2  .  join  ()   # Wait for thread 2 to finish   # Print the final count   print  (  f  'Actual Count:   {  ans  }   | Expected Count:   {  MAX     *     2  }  '  )   if   __name__   ==   '__main__'  :   main  ()   
JavaScript
   const     flag     =     [  0       0  ];   let     turn     =     0  ;   const     MAX     =     1e9  ;   let     ans     =     0  ;   function     lock_init  ()     {      flag  [  0  ]     =     flag  [  1  ]     =     0  ;      turn     =     0  ;   }   function     lock  (  self  )     {      flag  [  self  ]     =     1  ;      turn     =     1     -     self  ;      while     (  flag  [  1     -     self  ]     ===     1     &&     turn     ===     1     -     self  );   }   function     unlock  (  self  )     {      flag  [  self  ]     =     0  ;   }   async     function     func  (  self  )     {      let     i     =     0  ;      console  .  log  (  'Thread Entered:'       self  );      lock  (  self  );      for     (  i     =     0  ;     i      <     MAX  ;     i  ++  )      ans  ++  ;      unlock  (  self  );   }   async     function     main  ()     {      lock_init  ();      const     promise1     =     func  (  0  );      const     promise2     =     func  (  1  );      await     Promise  .  all  ([  promise1       promise2  ]);      console  .  log  (  'Actual Count:'       ans       '| Expected Count:'       MAX     *     2  );   }   main  ();   //This code is contribuited by Prachi.   

Çıkış: 

 Thread Entered: 1   
Thread Entered: 0
Actual Count: 2000000000 | Expected Count: 2000000000

Üretilen çıktı 2*10 9 nerede 10 9 her iki iş parçacığı tarafından artırılır.

Hakkında daha fazlasını okuyun Karşılıklı Dışlama için Peterson Algoritması | 2'yi ayarla