利用信号量机制解决哲学家进餐问题.docx
《利用信号量机制解决哲学家进餐问题.docx》由会员分享,可在线阅读,更多相关《利用信号量机制解决哲学家进餐问题.docx(11页珍藏版)》请在冰豆网上搜索。
利用信号量机制解决哲学家进餐问题
利用信号量机制解决哲学家进餐问题
成绩:
课程设计报告
课程名称:
课程设计(UNIX程序设计)
设计题目:
利用信号量机制解决哲学家进餐问题
姓名:
专业:
网络工程
班级:
学号:
计算机科学与技术学院
网络系
2013年12月28日
EATING进餐状态EAT
N
Y
N
Y
YN
一、原程序清单
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#defineN5
#defineLEFT(i)(i+N-1)%N
#defineRIGHT(i)(i+1)%N
#defineTHINKING0
#defineEATING1
//#include"behavior_philosophy.h"
voidphilosopher(int,char*,int,int,void(*)(int,int),void(*)(int,int));
voidtake_forks(int,char*,int,int,void(*)(int,int),void(*)(int,int));
voidput_forks(int,char*,int,int,void(*)(int,int),void(*)(int,int));
voidtest(int,char*,int,void(*)(int,int));
voidthink(int);
voideat(int);
voidP(int,int);
voidV(int,int);
/*------------------------哲学家动作-----------------*/
voidphilosopher(inti,char*state,intsem_phiid,intsem_mutexid,void(*P)(int,int),void(*V)(int,int)){
sleep
(1);
think(i);
while
(1){
take_forks(i,state,sem_phiid,sem_mutexid,P,V);
eat(i);
put_forks(i,state,sem_phiid,sem_mutexid,P,V);
think(i);
}
}
voidtake_forks(inti,char*state,intsem_phiid,intsem_mutexid,void(*P)(int,int),void(*V)(int,int)){
(*P)(sem_mutexid,0);
state[i]=THINKING;
test(i,state,sem_phiid,V);
(*V)(sem_mutexid,0);
(*P)(sem_phiid,i);
}
voidput_forks(inti,char*state,intsem_phiid,intsem_mutexid,void(*P)(int,int),void(*V)(int,int)){
(*P)(sem_mutexid,0);
state[i]=THINKING;
test(LEFT(i),state,sem_phiid,V);
test(RIGHT(i),state,sem_phiid,V);
(*V)(sem_mutexid,0);
}
voidtest(inti,char*state,intsem_phiid,void(*V)(int,int)){
if(state[i]==THINKING&&state[LEFT(i)]!
=EATING&&state[RIGHT(i)]!
=EATING){
state[i]=EATING;
(*V)(sem_phiid,i);
}
}
voidthink(inti){
printf("philosopher:
%d>>>>>isTHINKING.\n",i);
}
voideat(inti){
printf("I'mphilosopher:
%d>>>>>isEATING.andwilleating%dseconds!
\n",i,sleep
(2));
}
/*---------------------P,V原子操作------------*/
voidP(intsemid,intindex){
structsembufsema_buffer;
sema_buffer.sem_num=index;
sema_buffer.sem_op=-1;
sema_buffer.sem_flg=SEM_UNDO;
semop(semid,&sema_buffer,1);
}
voidV(intsemid,intindex){
structsembufsema_buf;
sema_buf.sem_num=index;
sema_buf.sem_op=1;
sema_buf.sem_flg=SEM_UNDO;
semop(semid,&sema_buf,1);
}
/*-----------------------------------------------------------*/
intmain()
{
/*-------------------------创建信号量操作----------------*/
intsem_phiid;
sem_phiid=semget(1008,5,0666|IPC_CREAT);
assert(sem_phiid>=0);
unsignedshortarray[5]={0,0,0,0,0};
unionsemun{
intval;
unsignedshort*array;
}semopts;
semopts.array=array;
intret1=semctl(sem_phiid,0,SETALL,semopts);
assert(ret1==0);
intsem_mutexid;
sem_mutexid=semget(0x225,1,0666|IPC_CREAT);
assert(sem_mutexid>=0);
semopts.val=1;
intret2=semctl(sem_mutexid,0,SETVAL,semopts);
assert(ret2==0);
/*------------------初始化共享内存-----------------------*/
intshmid;
char*state;
if((shmid=shmget(IPC_PRIVATE,N,0600|IPC_CREAT))==-1){
semctl(sem_phiid,0,IPC_RMID,0);
semctl(sem_mutexid,0,IPC_RMID,0);
perror("shmgetfaild!
");
exit
(1);
}
if((state=shmat(shmid,0,0))==(char*)-1){
semctl(sem_phiid,0,IPC_RMID,0);
semctl(sem_mutexid,0,IPC_RMID,0);
perror("shmatfaild!
");
exit
(1);
}
/*-----------------------------------------------*/
inti,phinum;
pid_tpid;
for(i=0;i<5;i++){
while((pid=fork())==-1);
if(!
pid){
phinum=i;
signal(SIGINT,SIG_DFL);
break;
}
}
if(pid>0){
while(wait((int*)0)==-1);
semctl(sem_phiid,0,IPC_RMID,0);
semctl(sem_mutexid,0,IPC_RMID,0);
shmdt(state);
printf("Hi,GAMEOVER!
");
}
else
philosopher(phinum,state,sem_phiid,sem_mutexid,P,V);
}
二、程序运行结果
截图一
截图二
截图三
三、设计总结
这次课程设计通过利用UNIX系统的信号量机制和共享内存机制,编写一个解决哲学家进餐问题的程序,感觉有很多收获,主要体现在以下几点:
(1)很好的复习了UNIX系统编程课上所学的知识,尤其是对unix进程通信机制中信号量机制和共享内存机制有了实践和更深的认识。
(2)练习了C编程,尤其是对函数指针有了更深的认识。
(3)复习了操作系统进程通信的原理。