Dining Philosopher Program C

佐手、 提交于 2020-01-03 06:35:30

问题


I am working with the classic dining philosopher problem with 5 philosophers and 5 chopsticks. My homework is to use 1 mutex and 5 conditions. I got it working but I don't know why philosopher 1 never eats, but 4,3,0 eat and 2 eats twice. Here's my code (sorry for the length):

//To compile: gcc -pthread -o monitor monitor.c 
//To execute: ./monitor "an integer as the amount of food (default = 5)" 

#include <pthread.h> 
#include <stdio.h>
#include <stdlib.h> 
// There are 5 philosophers (0,1,2,3,4) and 5 chopsticks (0,1,2,3,4)
#define NUM 5

// States of a philosopher
#define THINKING 0
#define HUNGRY 1
#define EATING 2

int food = 5; //The total amount of food on the table.
int monitor = HUNGRY;
int state[NUM]; //The state of a particular philosopher during the simulation

//The mutex for monitor variable and the condition resource_ready
pthread_mutex_t monitor_mutex;
pthread_cond_t resource_ready;
//The philosopher thread identifiers 
pthread_t philo[NUM];
void *philosopher (void *num); 
void get_chopsticks (int, int, int);
void test (int);
void put_chopsticks (int, int, int);

int main (int argc, char **argv) 
{ 
    if (argc == 2)
        food = atoi (argv[1]);
    int i;   

    pthread_mutex_init (&monitor_mutex, NULL);
    pthread_cond_init (&resource_ready, NULL);

    //Create a thread for each philosopher
    for (i = 0; i < NUM; i++) 
        pthread_create (&philo[i], NULL, philosopher, (void *)i);

    //Wait for the threads to exit 
    for (i = 0; i < NUM; i++) 
        pthread_join (philo[i], NULL);
    return 0; 
}
void *philosopher (void *num) 
{ 
    int id; 
    int i, left_chopstick, right_chopstick, f; 

    id = (int)num; //This is the philosopher's id

    state[id] = THINKING;
    printf ("Philosopher %d is thinking.\n", id);

    //Identify the philosopher's right and left chopstick 
    right_chopstick = id; 
    left_chopstick = (id + 1)%NUM; 

    //While there is still food on the table, the loop goes on  
    while (food > 0) 
    {
        //Get the chopstick
        get_chopsticks (id, left_chopstick, right_chopstick);
        sleep(1);       
    }
    return (NULL); 
}
void get_chopsticks (int phil, int c1, int c2) 
{
    //Lock monitor variable
    pthread_mutex_lock (&monitor_mutex);    
    state[phil] = monitor;//state[phil] = HUNGRY
    test(phil);
    if (state[phil] != EATING)
    {
        pthread_cond_wait (&resource_ready, &monitor_mutex);
        printf ("Philosopher %d is now eating\n", phil);
        food--; //1 food is eaten
        if (food == 0)
        {
                 printf ("There is no more food on the table. Program exit\n");
                 pthread_mutex_destroy(&monitor_mutex);
                 pthread_cond_destroy(&resource_ready);
                 exit(1);
            }
        printf ("There are/is %d food(s) left\n", food);
        put_chopsticks (phil, c1, c2);
        sleep(1);       
    }
    //Unlock monitor variable   
    pthread_mutex_unlock (&monitor_mutex); 
}

void test (int phil)
{
    //If the philosopher is hungry and the nearest 2 are not eating, he then eats.
    if ((state[(phil+4)%NUM] != EATING)&& (state[phil] == HUNGRY))
    {
        state[phil] = EATING;
        pthread_cond_signal (&resource_ready);
    }
}
void put_chopsticks (int phil, int c1, int c2) 
{
    state[phil] = THINKING;
    //Check the 2 nearest philosophers to see if they are eating
    test ((phil+4)%NUM);
    test ((phil+1)%NUM);
}

回答1:


You should #define NUM 5 instead of #define NUM 7. This is causing your modular arithmetic in put_chopsticks() and test()to be wrong and probably other odd things.

You also seem to have a race condition in the int you pass to the philosopher threads, since they all point to the same index address of i (and you should be getting compiler warning about wrong types here too).

I've stopped at this point, as you have too many issues here, those are just to start.




回答2:


The position of the right chopstick is same as the position of the philosopher. so according to your code, the 1st philosopher will never have the chopstick of the 5th philosopher (which contradicts the idea that they are sitting on circular table).

So simply try this in your <void *philosopher (void *num)> function

right_chopstick = (id+1)%NUM ;
left_chopstick = (id+(NUM-1))%NUM;

I hope this will allow your first philosopher to eat

& to make all philosophers eat, try to introduce sleep time when they change their state from THINKING to EATING & vice-versa.



来源:https://stackoverflow.com/questions/23529773/dining-philosopher-program-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!