logo

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*109nerede 109her 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
 



SDLC