• IPC----哲学家就餐问题(并发与互斥)


    哲学家就餐问题描述:

      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
    ");
    	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
    ",no);
    		 sleep(rand()%5+1);
    		 printf("philosophere %d is hungry
    ",no);
    		 //sleep(rand()%5+1);
    		 wait_for_2fork(no);         //等待获取刀叉
    		 printf("philosophere %d is eating
    ",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
    ");
    		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
    ");
    			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

  • 相关阅读:
    Git 一些常用命令
    Opengl VS2008开发环境
    用 HTML5 给 iPad,iPhone 打造速度超快的应用_HTML5研究小组
    理解CSS3 transform中的Matrix(矩阵) « 张鑫旭鑫空间鑫生活
    Google Dremel 原理 如何能 3 秒分析 1PB 开源中国社区
    Perl:过滤注释
    HTML5 History API实现无刷新跳转 蓝飞技术部落格 —— 关注前沿,追求卓越。
    OPENGL编程指南
    Perl : Quantifier follows nothing in regex; marked by
    .js文件无法运行的方法
  • 原文地址:https://www.cnblogs.com/wujing-hubei/p/5743720.html
Copyright © 2020-2023  润新知