问题描述:
有五个哲学家公用一张餐桌,分别坐在周围的五张椅子上,在餐桌上有五个碗和五只筷子,他们的生活方式是交替地进行思考和用餐。平时,一个哲学家进行思考,饥饿时便试图拿取其左右最靠近他的筷子,只有在他拿到两只筷子时才能进餐,进餐完毕,放下筷子继续思考。(计算机操作系统 第三版)
书上为代码:
Var chopstick: array[0,...,4] of semaphore;
repeat
wait(chopstick[i]);
wait(chopstick[(i+1)%5])
.
.
eat:
.
.
signal(chopstick[i])
signal(opstick[(i+1)%5])
.
.
think:
until false;
这样当五个哲学家同时饥饿时而各自拿起左边的筷子是,就会使五个信号量chopstick均为0;当他们再试图去拿右边的筷子时,都将因没有筷子可拿而无限地等待。从而导致死锁。
本文解决死锁的策略是:只有当哲学家的左右两只筷子均可以用的时候,才允许其拿起筷子进餐,否则则该哲学家一直请求左边的筷子保持阻塞状态(左边的筷子信号量为1则直接占有,信号量为0则进入阻塞状态),右边的筷子若信号量为0,则非阻塞,进入等待。
详细代码:
/*
* philosopher.c
*
* Created on: 2012-12-17
* Author: xkey
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
#include <string.h>
#define PEOPLE_NUM 5
#define THINKING 1
#define HUNGRY 2
#define EATING 3
sem_t chopsticks[PEOPLE_NUM];
pthread_mutex_t mutex;
void *philosopher(void *arg){
int id = (int) arg;
int state = THINKING;
int right = (id + 1) % PEOPLE_NUM;
int left = (id + PEOPLE_NUM - 1) % PEOPLE_NUM;
char ptrState[32];
while(1){
switch(state){
case THINK