Problema del filósofo comedor usando semáforos

Requisito previo: sincronización de procesos , semáforos , cena-filósofos Solución usando monitores
El problema del filósofo cenador: el problema del filósofo cenador establece que los filósofos K se sientan alrededor de una mesa circular con un palillo entre cada par de filósofos. Hay un palillo entre cada filósofo. Un filósofo puede comer si puede recoger los dos palillos adyacentes a él. Un palillo puede ser recogido por cualquiera de sus seguidores adyacentes, pero no por ambos. 
 

Solución de semáforo para cenar filósofo:
cada filósofo está representado por el siguiente pseudocódigo: 
 

process P[i]
 while true do
   {  THINK;
      PICKUP(CHOPSTICK[i], CHOPSTICK[i+1 mod 5]);
      EAT;
      PUTDOWN(CHOPSTICK[i], CHOPSTICK[i+1 mod 5])
   }

Hay tres estados del filósofo: PENSAMIENTO, HAMBRE y COMER . Aquí hay dos semáforos: Mutex y una array de semáforos para los filósofos. Mutex se usa de tal manera que dos filósofos no pueden acceder al retiro o al retiro al mismo tiempo. La array se utiliza para controlar el comportamiento de cada filósofo. Sin embargo, los semáforos pueden resultar en interbloqueos debido a errores de programación.
Código – 
 

C

#include <pthread.h>
#include <semaphore.h>
#include <stdio.h>
 
#define N 5
#define THINKING 2
#define HUNGRY 1
#define EATING 0
#define LEFT (phnum + 4) % N
#define RIGHT (phnum + 1) % N
 
int state[N];
int phil[N] = { 0, 1, 2, 3, 4 };
 
sem_t mutex;
sem_t S[N];
 
void test(int phnum)
{
    if (state[phnum] == HUNGRY
        && state[LEFT] != EATING
        && state[RIGHT] != EATING) {
        // state that eating
        state[phnum] = EATING;
 
        sleep(2);
 
        printf("Philosopher %d takes fork %d and %d\n",
                      phnum + 1, LEFT + 1, phnum + 1);
 
        printf("Philosopher %d is Eating\n", phnum + 1);
 
        // sem_post(&S[phnum]) has no effect
        // during takefork
        // used to wake up hungry philosophers
        // during putfork
        sem_post(&S[phnum]);
    }
}
 
// take up chopsticks
void take_fork(int phnum)
{
 
    sem_wait(&mutex);
 
    // state that hungry
    state[phnum] = HUNGRY;
 
    printf("Philosopher %d is Hungry\n", phnum + 1);
 
    // eat if neighbours are not eating
    test(phnum);
 
    sem_post(&mutex);
 
    // if unable to eat wait to be signalled
    sem_wait(&S[phnum]);
 
    sleep(1);
}
 
// put down chopsticks
void put_fork(int phnum)
{
 
    sem_wait(&mutex);
 
    // state that thinking
    state[phnum] = THINKING;
 
    printf("Philosopher %d putting fork %d and %d down\n",
           phnum + 1, LEFT + 1, phnum + 1);
    printf("Philosopher %d is thinking\n", phnum + 1);
 
    test(LEFT);
    test(RIGHT);
 
    sem_post(&mutex);
}
 
void* philosopher(void* num)
{
 
    while (1) {
 
        int* i = num;
 
        sleep(1);
 
        take_fork(*i);
 
        sleep(0);
 
        put_fork(*i);
    }
}
 
int main()
{
 
    int i;
    pthread_t thread_id[N];
 
    // initialize the semaphores
    sem_init(&mutex, 0, 1);
 
    for (i = 0; i < N; i++)
 
        sem_init(&S[i], 0, 0);
 
    for (i = 0; i < N; i++) {
 
        // create philosopher processes
        pthread_create(&thread_id[i], NULL,
                       philosopher, &phil[i]);
 
        printf("Philosopher %d is thinking\n", i + 1);
    }
 
    for (i = 0; i < N; i++)
 
        pthread_join(thread_id[i], NULL);
}

Nota: el siguiente programa puede compilarse solo con compiladores C con semáforo y biblioteca pthread.
Referencias –  
Solución de los filósofos gastronómicos – cs.gordon.edu  
Solución de los filósofos gastronómicos – cs.indiana.edu
 

Publicación traducida automáticamente

Artículo escrito por Subham Biswas y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *