2014-05-07 40 views
-1

我正在與5個哲學家和5個筷子的經典餐飲哲學家問題。我的作業是使用1個互斥體和5個條件。我得到它的工作,但我不知道爲什麼哲學家1從不吃,但4,3,0吃,2吃兩次。這裏是我的代碼(遺憾的長度):餐飲哲學家計劃C

//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

你爲什麼要做'#定義NUM 7'而不是'5'? – JohnH

+0

維基百科關於餐飲哲學家問題的文章提出了幾種不同的算法來解決這個問題。你想要實現哪種算法? – user3386109

+0

@ user3386109我正在嘗試實施資源層次結構解決方案(用維基百科條款) – user3335367

回答

0

#define NUM 7你應該#define NUM 5代替。這導致您的模塊算術put_chopsticks()test()是錯誤的,可能是其他奇怪的事情。因爲它們都指向相同的索引地址i(並且你也應該在這裏得到關於錯誤類型的編譯器警告)。在你傳遞給哲學家線程的int中你似乎也有一個競爭條件,因爲它們都指向相同的索引地址i

我已經停止在這一點,因爲你有太多的問題在這裏,那些只是開始。

+0

糟糕我想改變一下,我只是在玩代碼 – user3335367

0

右筷子的位置與哲學家的位置相同。所以根據你的代碼,第一哲學家將永遠不會擁有第五哲學家的筷子(這與他們坐在圓桌上的觀點相矛盾)。

所以乾脆試試這個在您的<void *philosopher (void *num)>功能

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

我希望這可以讓你的第一個哲學家吃

&使所有的哲學家吃,嘗試當他們改變自己的狀態,以引進的睡眠時間從思考到食用&反之亦然。