这里为哲学家就餐问题提供的解决方案指出:只有当左右筷子都可用时,才允许哲学家拿起筷子。我正在为该解决方案使用以下代码。然而,唯一的问题是存在饥饿的可能性。解决此问题的最有效解决方案是什么?
主程序
/*Solution to dining philosophers using POSIX mutexes and condition varaibles.*/
#include <pthread.h>
#include <stdio.h>
#include "dp.h"
pthread_t tid[NUMBER];
/**
* Initialize all relevant data structures and
* synchronization objects.
*/
void init()
{
int i;
for (i = 0; i < NUMBER; i++) {
state[i] = THINKING;
thread_id[i] = i;
pthread_cond_init(&cond_vars[i],NULL);
}
pthread_mutex_init(&mutex_lock, NULL);
}
void create_philosophers()
{
int i;
for (i = 0; i < NUMBER; i++) {
pthread_create(&tid[i], 0, philosopher, (void *)&thread_id[i]);
}
}
int main(void)
{
int i;
init();
create_philosophers();
for (i = 0; i < NUMBER; i++)
pthread_join(tid[i],NULL);
return 0;
}
吃.c
/*simulate eating*/
#include <stdio.h>
void eating(int sleep_time)
{
//printf("eating for %d seconds\n",sleep_time);
sleep(sleep_time);
}
哲学家.c
/*General structure of a dining philosopher*/
#include <pthread.h>
#include <stdio.h>
#include <time.h>
#include "dp.h"
void *philosopher(void *param)
{
int *lnumber = (int *)param;
int number = *lnumber;
int sleep_time;
int times_through_loop = 0;
srandom((unsigned)time(NULL));
while (times_through_loop < 5) {
sleep_time = (int)((random() % MAX_SLEEP_TIME) + 1);
thinking(sleep_time);
pickup_forks(number);
printf("Philosopher %d is eating\n",number);
sleep_time = (int)((random() % MAX_SLEEP_TIME) + 1);
eating(sleep_time);
printf("Philosopher %d is thinking\n",number);
return_forks(number);
++times_through_loop;
}
}
思考.c
/*simulate thinking*/
#include <stdio.h>
void thinking(int sleep_time)
{
//printf("thinking for %d seconds",sleep_time);
sleep(sleep_time);
}
餐饮.c
/*Solution to dining philosophers using POSIX mutexes and condition varaibles.*/
#include <pthread.h>
#include <stdio.h>
#include "dp.h"
/* return the left neighbor */
int left_neighbor(int number)
{
if (number == 0)
return NUMBER - 1;
else
return number - 1;
}
/* return the right neighbor */
int right_neighbor(int number)
{
if (number == NUMBER - 1)
return 0;
else
return number + 1;
}
void test(int i)
{
/**
* Basic idea is this:
* If I'm hungry, and my left and right neighbors aren't eating, then let me eat.
*/
if ( (state[left_neighbor(i)] != EATING) && (state[i] == HUNGRY) && (state[right_neighbor(i)] != EATING) ) {
state[i] = EATING;
pthread_cond_signal(&cond_vars[i]);
}
}
/* A philosopher calls this when it wants to pick up its forks./
void pickup_forks(int number)
{
pthread_mutex_lock(&mutex_lock);
state[number] = HUNGRY;
test(number);
while (state[number] != EATING) {
pthread_cond_wait(&cond_vars[number], &mutex_lock);
}
pthread_mutex_unlock(&mutex_lock);
}
/* A philosopher calls this when it wants to return its forks./
void return_forks(int number)
{
pthread_mutex_lock(&mutex_lock);
state[number] = THINKING;
test(left_neighbor(number));
test(right_neighbor(number));
pthread_mutex_unlock(&mutex_lock);
}
dp.h
/*Header file for dining philosophers*/
#include <pthread.h>
// the number of philosophers
#define NUMBER 5
// the maximum time (in seconds) to sleep
#define MAX_SLEEP_TIME 5
// different philosopher states
//#define THINKING 0
//#define HUNGRY 1
//#define EATING 2
// the state of each philosopher (THINKING, HUNGRY, EATING)
//int state[NUMBER];
enum {THINKING, HUNGRY, EATING} state[NUMBER];
// the thread id of each philosopher (0 .. NUMBER - 1)
int thread_id[NUMBER];
// condition variables and associated mutex lock
pthread_cond_t cond_vars[NUMBER];
pthread_mutex_t mutex_lock;
void *philosopher(void *param);
生成文件
# To run, enter
# make all
all: diningphilosophers
diningphilosophers: main.o dining.o eating.o thinking.o philosopher.o
gcc -lpthread -o diningphilosophers main.o dining.o thinking.o eating.o philosopher.o
main.o: main.c dp.h
gcc -lpthread -c main.c
dining.o: dining.c dp.h
gcc -lpthread -c dining.c
philosopher.o: philosopher.c dp.h
gcc -lpthread -c philosopher.c
eating.o: eating.c
gcc -lpthread -c eating.c
thinking.o: thinking.c
gcc -lpthread -c thinking.c
``