标签:
哲学家就餐问题描述:
5个哲学家,5个筷子。5个哲学家围坐在一张桌子上,筷子放在分别放在每个哲学家的两旁。如果所有哲学家在某个时刻同时拿起左边的筷子,那么右边的筷子就都被其他的哲学家拿了,造成大家都无法吃饭。但是大家都不想放下左边的筷子(规则是先拿起左边筷子在拿起右边的,吃完饭在放下两个筷子),这就是死锁。
解决这个问题有个办法是
在拿起筷子前先判断左右两个筷子是否可用,可用才能拿,而且是同时拿,这样不相邻的哲学家就可以吃上饭,不会造成死锁。
实现代码如下
#include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> union semun { int val; /* Value for SETVAL */ struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */ unsigned short *array; /* Array for GETALL, SETALL */ struct seminfo *__buf; /* Buffer for IPC_INFO (Linux-specific) */ }; //用于设置信号量所需要的联合体 int semid; int sem_del(int semid) //删除一个信号量集 { int ret; ret=semctl(semid,0,IPC_RMID,0); //不知道信号量集合中有几个信号量,故对第2个参数设为0 if (ret==-1) printf("semdel falied\n"); return 0; } void wait_for_2fork(int no) { int left =no; //左刀叉 int right = (no+1)%5; //右刀叉 struct sembuf buf[2] ={{left,-1,0},{right,-1,0}}; //-1表示为P操作 semop(semid,buf,2); //等待获取刀叉(资源) } void free_2fork(int no) { int left =no; //左刀叉 int right = (no+1)%5; //右刀叉 struct sembuf buf[2] ={{left,1,0},{right,1,0}}; //-1表示为P操作 semop(semid,buf,2); //释放获取的刀叉(资源) } void phliosophere(int no) { srand(getpid()); //以进程号作为随机数的种子 while(1) { printf("philosophere %d is thinking\n",no); sleep(rand()%5+1); printf("philosophere %d is hungry\n",no); //sleep(rand()%5+1); wait_for_2fork(no); //等待获取刀叉 printf("philosophere %d is eating\n",no); sleep(rand()%5+1); free_2fork(no); //释放刀叉 } } int main() { //int semid; semid=semget(IPC_PRIVATE,5,IPC_CREAT|0666); //创建5个私有信号量,每一个信号量相当于一把叉子 if(semid==-1) { printf("semget failed\n"); return 0; } union semun su; su.val=1; int i; for(i=0;i<5;i++) semctl(semid,i,SETVAL,su); //初始化信号量 int no=0; //进程id pid_t pid; for(i=0;i<5;i++) { pid=fork(); if(pid==-1) { printf("fork failed\n"); return 0; } if(pid==0) //子进程 { no=i; break; } } phliosophere(no); //哲学家行为实现 return 0; }
新问题描述:
设有5个哲学家,共享一张放有5把椅子的桌子,每人分得一把椅子,但是,桌子上共有5只筷子,在每人两边各放一只,哲学家们在肚子饥饿时才试图分两次从两边拿起筷子就餐。
条件:
1)拿到两只筷子时哲学家才开始吃饭。
2)如果筷子已在他人手上,则该哲学家必须等他人吃完之后才能拿到筷子。
3)任一哲学家在自己未拿到两只筷子前却不放下自己手中的筷子。
试:
1)描述一 个保证不会出现两个邻座同时要求吃饭的通信算法。
2)描述一个即没有两个邻座同时吃饭,有没有饿死(永远拿不到筷子)的算法
见参考2
参考:
用信号量解决哲学家就餐问题 http://www.oschina.net/code/snippet_724028_36857
操作系统并发和互斥:哲学家进餐问题 http://blog.sina.com.cn/s/blog_759803690101d9ne.html
哲学家就餐问题linux下c++代码 http://blog.sina.com.cn/s/blog_704553390100uq75.html
标签:
原文地址:http://www.cnblogs.com/wujing-hubei/p/5743720.html