1

I am trying to solve the Philosophers Dining Problem using semaphores. The philosopher first picks up the left fork and then right fork and when finished eating puts them down. I am implementing this using 5 threads one for each philosopher and 5 semaphores one for each chopstick. Need to perform a deadlock check by the parent and break the deadlock if found. When I just run the cycle of philosopher THINKING and EATINGthe program crashes with the error The futex facility returned an unexpected error code.Aborted. I am not getting any information on how to debug this error.

The Thread of the Philosoper is given below

void *Philospoher_behaviour(void *param){
int id  = *(int *)param; // assigns a ID to the Phil
int state; // hungry , thinking, eating
// first the philopher thinks
while(1) {
    state = THINKING;
    float time = (float)rand()/RAND_MAX;
    printf("Philosopher %d starts THINKING for %f\n",id,time);
    sleep(time);
    // the phil goes hungrg
    state = HUNGRY;
    printf("Philosopher %d is now HUNGRY\n",id);
    // first wait for left
    sem_wait(&chopsticks[id]);
    printf("Philosopher %d grabs chopstick %d to this LEFT\n",id,id);

    // got left chopstick
    sem_wait(&chopsticks[(id+1)%5]);
    printf("Philosopher %d grabs chopstick %d to this RIGHT\n",id,(id+1)%5);

    // got the right chopstick
    state = EATING;
    time = (float)rand()/RAND_MAX;
    printf("Philosopher %d starts EATING for time  %f\n",id,time);

    sleep(time);

    sem_post(&chopsticks[(id + 1)%5]);
    printf("Philosopher %d releases chopstick %d to this RIGHT\n",id,(id+1)%5);
    sem_post(&chopsticks[id]);
    printf("Philosopher %d releases chopstick %d to this LEFT\n",id,(id));
    state = THINKING;

    time = (float)rand()/RAND_MAX;
    sleep(time);

}

}

The Main program is as follows

sem_t chopsticks[5];// five chopsticks as a resource
pthread_t philosopher[5]; //five philosoophers

int main(){
srand(time(NULL));
for ( int i=0 ;i <5;i++){
    sem_init(&chopsticks[i], 0, 1); // local to the threads with initial value of 1
}

// now create the indiviual threads
for(int i=0;i<5;i++){
    if( pthread_create(&philosopher[i],NULL, Philospoher_behaviour ,&i) != 0) { // create thread one
        printf("Cant create thread %d\n",i);
        return 1;
    }
    else{
        printf("Creadted Philosopher Number : %d\n",i);
    }
}

for(int i=0;i<5;i++){
    pthread_join(philosopher[i],NULL);
}

}

How to debug this error. I am also pasting the output of one run

Creadted Philosopher Number : 0
Philosopher 1 starts THINKING for 0.483853
Creadted Philosopher Number : 1
Philosopher 1 starts THINKING for 0.059081
Creadted Philosopher Number : 2
Philosopher 3 starts THINKING for 0.149168
Creadted Philosopher Number : 3
Philosopher 4 starts THINKING for 0.073436
Creadted Philosopher Number : 4
Philosopher 5 starts THINKING for 0.833351
Philosopher 5 is now HUNGRY
Philosopher 1 is now HUNGRY
Philosopher 5 grabs chopstick 5 to this LEFT
Philosopher 1 grabs chopstick 1 to this LEFT
Philosopher 1 grabs chopstick 2 to this RIGHT
Philosopher 1 starts EATING for time  0.147257
Philosopher 3 is now HUNGRY
Philosopher 3 grabs chopstick 3 to this LEFT
Philosopher 3 grabs chopstick 4 to this RIGHT
Philosopher 1 is now HUNGRY
Philosopher 3 starts EATING for time  0.572829
Philosopher 4 is now HUNGRY
Philosopher 1 releases chopstick 2 to this RIGHT
Philosopher 1 releases chopstick 1 to this LEFT
Philosopher 5 grabs chopstick 1 to this RIGHT
Philosopher 5 starts EATING for time  0.857843
Philosopher 3 releases chopstick 4 to this RIGHT
Philosopher 3 releases chopstick 3 to this LEFT
Philosopher 4 grabs chopstick 4 to this LEFT
Philosopher 4 grabs chopstick 0 to this RIGHT
Philosopher 4 starts EATING for time  0.783497
Philosopher 1 starts THINKING for 0.308573
Philosopher 5 releases chopstick 1 to this RIGHT
Philosopher 4 releases chopstick 0 to this RIGHT
Philosopher 4 releases chopstick 4 to this LEFT
Philosopher 1 grabs chopstick 1 to this LEFT
Philosopher 3 starts THINKING for 0.086635
Philosopher 1 grabs chopstick 2 to this RIGHT
Philosopher 1 starts EATING for time  0.015005
The futex facility returned an unexpected error code.Aborted

There also one issue as you can see there are no interactions by Philosopher 0 and 2 why is this happening.

Running it in the GDB I get this information

Thread 6 "part22" received signal SIGABRT, Aborted.
[Switching to Thread 0x7ffff57eb700 (LWP 12247)]
0x00007ffff7825428 in __GI_raise (sig=sig@entry=6)
    at ../sysdeps/unix/sysv/linux/raise.c:54
54  ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
Dhawal Gupta
  • 11
  • 1
  • 3
  • One of your errors is that you do not capture the return of the `sem_` functions. Other than the theory books might suggest, these are low level tools that can (and will!) be interrupted, e.g if your process receives IO. Basically they are not the right tools for learning parallelism, because they are much too complex to use correctly. If you have to (this looks like an assignment) you'd have to wrap `sem_wait` in a loop, handle all its possible errors and try again if you encountered a transitional error. – Jens Gustedt Feb 09 '18 at 22:22

1 Answers1

3

You're passing the address of your main() loop variable i to each thread:

pthread_create(&philosopher[i],NULL, Philospoher_behaviour ,&i)

By the time your thread executes

int id  = *(int *)param;

the value in i may have changed.

Andrew Henle
  • 32,625
  • 3
  • 24
  • 56
  • Okay I have changed that by using an array of numbers i.e. `id[5] = {0,1,2,3,4} ` and passing `&id[i]`. So was this the reason for this error. – Dhawal Gupta Feb 10 '18 at 05:22