# 算法设计：用信号量来解决哲学家问题

2021年4月9日16:33:45 发表评论 1,138 次浏览

``````process P[i]
while true do
{  THINK;
PICKUP(CHOPSTICK[i], CHOPSTICK[i+1 mod 5]);
EAT;
PUTDOWN(CHOPSTICK[i], CHOPSTICK[i+1 mod 5])
}``````

``````#include <pthread.h>
#include <semaphore.h>
#include <stdio.h>

#define N 5
#define THINKING 2
#define HUNGRY 1
#define EATING 0
#define LEFT (phnum + 4) % N
#define RIGHT (phnum + 1) % N

int state[N];
int phil[N] = { 0, 1, 2, 3, 4 };

sem_t mutex;
sem_t S[N];

void test( int phnum)
{
if (state[phnum] == HUNGRY
&& state[LEFT] != EATING
&& state[RIGHT] != EATING) {
//state that eating
state[phnum] = EATING;

sleep(2);

printf ( "Philosopher %d takes fork %d and %d\n" , phnum + 1, LEFT + 1, phnum + 1);

printf ( "Philosopher %d is Eating\n" , phnum + 1);

//sem_post(&S[phnum]) has no effect
//during takefork
//used to wake up hungry philosophers
//during putfork
sem_post(&S[phnum]);
}
}

//take up chopsticks
void take_fork( int phnum)
{

sem_wait(&mutex);

//state that hungry
state[phnum] = HUNGRY;

printf ( "Philosopher %d is Hungry\n" , phnum + 1);

//eat if neighbours are not eating
test(phnum);

sem_post(&mutex);

//if unable to eat wait to be signalled
sem_wait(&S[phnum]);

sleep(1);
}

//put down chopsticks
void put_fork( int phnum)
{

sem_wait(&mutex);

//state that thinking
state[phnum] = THINKING;

printf ( "Philosopher %d putting fork %d and %d down\n" , phnum + 1, LEFT + 1, phnum + 1);
printf ( "Philosopher %d is thinking\n" , phnum + 1);

test(LEFT);
test(RIGHT);

sem_post(&mutex);
}

void * philospher( void * num)
{

while (1) {

int * i = num;

sleep(1);

take_fork(*i);

sleep(0);

put_fork(*i);
}
}

int main()
{

int i;

//initialize the semaphores
sem_init(&mutex, 0, 1);

for (i = 0; i <N; i++)

sem_init(&S[i], 0, 0);

for (i = 0; i <N; i++) {

//create philosopher processes

printf ( "Philosopher %d is thinking\n" , i + 1);
}

for (i = 0; i <N; i++)