0

Having written the code regarding the dinner philosophers problem which avoids the deadlock, I now want to implement the code such that the deadlock occurs

I know that deadlock can occur if each of the philosophers is holding only one wand and waits to take the other one but I don't know how to proceed

The code is this:

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <semaphore.h>
#include <stdbool.h>

#define NUM_FIL 5
#define PENSA 2
#define AFFAMATO 1
#define MANGIA 0
#define SINISTRA (filosofi+4) % NUM_FIL
#define DESTRA (filosofi+1) % NUM_FIL

int stato[NUM_FIL];
int fil[NUM_FIL] = {0,1,2,3,4};

sem_t mutex;
sem_t F[NUM_FIL];

void schermoIniziale();
void verifica(int filosofi);
void prendeForchetta(int filosofi);
void lasciaForchetta(int filosofi);
void* filosofo(void* num);

void verifica(int filosofi){
    if (stato[filosofi] == AFFAMATO && stato[SINISTRA] == MANGIA && stato[DESTRA] != MANGIA) {
        stato[filosofi] = MANGIA;
        sleep(1);
        printf("Filosofo %d prende le forchette %d e %d\n", filosofi +1, SINISTRA+1, filosofi+1);
        printf("Filosofo %d MANGIA\n", filosofi+1);
        sem_post(&F[filosofi]);
    }
}

void lasciaForchetta(int filosofi){
    sem_wait(&mutex);
    stato[filosofi] = PENSA;
    printf("Filosofo %d lascia le forchette %d e %d \n",filosofi+1, SINISTRA+1, filosofi+1);
    printf("Filosofo %d PENSA\n", filosofi+1);
    verifica(SINISTRA);
    verifica(DESTRA);
    sem_post(&mutex);
}

void prendeForchetta(int filosofi){
    sem_wait(&mutex);
    stato[filosofi] = AFFAMATO;
    printf("Filosofo %d e' affamato\n", filosofi+1);
    verifica(filosofi);
    sem_post(&mutex);
    sem_wait(&F[filosofi]);
    sleep(1);
}

void* filosofo(void* num){
    while (true) {
        int* i = num;
        sleep(1);
        prendeForchetta(*i);
        sleep(1);
        lasciaForchetta(*i);
    }
}

int main(){
    int i;
    pthread_t fil_id[NUM_FIL];
    sem_init(&mutex,0,1);
    schermoIniziale();
    sleep(2);
    for (i = 0; i < NUM_FIL; i++){
        sem_init(&F[i],0,0);
    }
    for (i = 0; i < NUM_FIL; i++) {
        pthread_create(&fil_id[i], NULL, filosofo, &fil[i]);
        printf("Filosofo %d PENSA\n",i+1);
    }
    for (i = 0; i < NUM_FIL; i++){
        pthread_join(fil_id[i],NULL);
    }
}

void schermoIniziale(){
    printf("+-----------BENVENUTO------------+\n");
    printf("|   Dining philosophers problem  |\n");
    printf("+--------------------------------+\n\n");
}

1 Answers1

0

Your above implementation (after stato[SINISTRA] == MANGIA corrected to stato[SINISTRA] != MANGIA) always lets a philosopher take two forks at once. In order to make it possible that each of the philosophers is holding only one fork, we need to hold the state of each fork. I don't know what you intended to do with sem_t F[NUM_FIL]; let's use that as the fork states:

void lasciaForchetta(int filosofi)
{
    stato[filosofi] = PENSA;
    printf("Filosofo %d lascia le forchette %d e %d \n",
                     filosofi+1, SINISTRA+1, filosofi+1);
    sem_post(&F[SINISTRA]); // put down left hand fork
    sem_post(&F[filosofi]); // put down right hand fork
    printf("Filosofo %d PENSA\n", filosofi+1);
}

void prendeForchetta(int filosofi)
{
    stato[filosofi] = AFFAMATO;
    printf("Filosofo %d e' affamato\n", filosofi+1);
    sem_wait(&F[SINISTRA]); // take left hand fork
    printf("philosopher %d took first fork %d\n", filosofi+1, SINISTRA+1);
    /// sleep(1);   // put this in to enforce deadlock
    sem_wait(&F[filosofi]); // take right hand fork
    printf("philosopher %d took fork %d, eats\n", filosofi+1, filosofi+1);
    stato[filosofi] = MANGIA;
    sleep(1);
}
…
        sem_init(&F[i], 0, 1);  // all forks initially available

The insertion of a delay between a philosopher taking one fork and the other then makes it highly probable that a deadlock occurs.

Armali
  • 18,255
  • 14
  • 57
  • 171