📜  互斥的彼得森算法设置 1(基本 C 实现)

📅  最后修改于: 2022-05-13 01:56:11.672000             🧑  作者: Mango

互斥的彼得森算法设置 1(基本 C 实现)

问题:给定 2 个进程 i 和 j,您需要编写一个程序,无需任何额外的硬件支持即可保证两者之间互斥。

解决方案:可以有多种方法来解决这个问题,但大多数都需要额外的硬件支持。最简单和最流行的方法是使用彼得森算法进行互斥。它是由 Peterson 于 1981 年开发的,尽管在这个方向上的最初工作是由 Theodorus Jozef Dekker 完成的,他在 1960 年提出了 Dekker 算法,后来由 Peterson 改进并被称为Peterson 算法

基本上,Peterson 的算法通过仅使用共享内存来提供有保证的互斥。它在算法中使用了两个思想:

  1. 愿意获取锁。
  2. 转动获取锁。

先决条件:C 中的多线程

解释:

这个想法是首先一个线程表达它想要获取锁的愿望并设置flag[self] = 1 ,然后给另一个线程一个获取锁的机会。如果线程想要获取锁,那么它会获取锁并将机会传递给第一个线程。如果它不想获得锁,那么 while 循环就会中断,第一个线程就有机会了。



C语言实现

C
// Filename: peterson_spinlock.c
// Use below command to compile:
// gcc -pthread peterson_spinlock.c -o peterson_spinlock
 
#include 
#include 
#include"mythreads.h"
 
int flag[2];
int turn;
const int MAX = 1e9;
int ans = 0;
 
void lock_init()
{
    // Initialize lock by reseting the desire of
    // both the threads to acquire the locks.
    // And, giving turn to one of them.
    flag[0] = flag[1] = 0;
    turn = 0;
}
 
// Executed before entering critical section
void lock(int self)
{
    // Set flag[self] = 1 saying you want to acquire lock
    flag[self] = 1;
 
    // But, first give the other thread the chance to
    // acquire lock
    turn = 1-self;
 
    // Wait until the other thread looses the desire
    // to acquire lock or it is your turn to get the lock.
    while (flag[1-self]==1 && turn==1-self) ;
}
 
// Executed after leaving critical section
void unlock(int self)
{
    // You do not desire to acquire lock in future.
    // This will allow the other thread to acquire
    // the lock.
    flag[self] = 0;
}
 
// A Sample function run by two threads created
// in main()
void* func(void *s)
{
    int i = 0;
    int self = (int *)s;
    printf("Thread Entered: %d\n", self);
 
    lock(self);
 
    // Critical section (Only one thread
    // can enter here at a time)
    for (i=0; i


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__


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__

输出:

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

产生的输出是 2*10 9 ,其中 10 9由两个线程递增。