操作系统哲学家进餐实验_第1页
操作系统哲学家进餐实验_第2页
操作系统哲学家进餐实验_第3页
操作系统哲学家进餐实验_第4页
操作系统哲学家进餐实验_第5页
已阅读5页,还剩7页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

《操作系统》实验报告实验题目:哲学家进餐问题

一、实验目的:实现linux下哲学家进餐问题。体会如何控制进程同步与互斥的信号量方法。二、实验内容:运用linux下fork,IPC信号量机制中的相关系统调用,IPC共享存储器机制,实现哲学家进餐问题。三、编程环境及工具Linux下GCC四、具体设计要求及有关说明Fork()在子进程刚被创建时,它和父进程具有相同的共享正文段,而其他进程信息则完全拷贝父进程得到。信号量调用的示例程序:#include<sys/types.h>#include<sys/ipc.h>#include<sys/sem.h>#include<stdio.h>unionsemun{ intval; structsemid_ds*buf; ushort*array;}argument;intmain(){intid;/*Numberbywhichthesemaphoreisknownwithinaprogram*/argument.val=0;//新建一个信号量集合,包含一个信号量id=semget(IPC_PRIVATE,1,0666|IPC_CREAT);if(id<0){printf("Unabletoobtainsemaphore.\n");exit(-1);}//将信号量的值置为0if(semctl(id,0,SETVAL,argument)<0){printf("Cannotsetsemaphorevalue.\n");}else{printf("Semaphoreinitialized.\n");}}intlock_sem(intsemid,intmember){/*初始化sembuf结构,将指定信号量值减1。sem_flg指明操作的执行模式,它有两个标志位:IPC_NOWAIT(04000):指明以非阻塞方式操作信号灯,即如果信号灯不可使用,则不等待,立即返回。SEM_UNDO(010000):指明内核为信号灯操作保留恢复值,当进程调用exit退出时,内核自动为该进程恢复其操作以前的信号灯值。引进SEM_UNDO标志的作用是为了防止当进程异常退出时没有释放信号灯,而其它进程只能永远处于等待状态。*/structsembufsem_lock={member,-1,SEM_UNDO};//所要执行的是P操作intsemval;printf("----------------------------------inbegintogetsemaphore---------------------------------\n");semval=semctl(semid,member,GETVAL,0);//取得指定信号量的当前值printf("currentvalue=%d\n",semval);if(semop(semid,&sem_lock,1)==-1)//itwillbeblockeduntilgettheaccess

{printf("Lockfailed\n");return-1;}elseprintf("Semaphoreresourcesdecrementedbyone(locked)\n");semval=semctl(semid,member,GETVAL,0);//取得指定信号量的当前值,核对是否减了1printf("semvalformember%dis%d\n",member,semval);printf("-------------------------------------Hasgetsemaphore-------------------------------------\n");return0;}共享内存的使用五、实验结果及分析下图为程序结果显示,每个哲学家吃两次以后结束进程。程序过程:0试图去吃,发现旁边没人在吃,拿起筷子吃。1试图去吃,发现旁边有人在吃,1不能吃。等待旁边人吃完。2试图去吃,发现旁边没人在吃,2拿起筷子吃。3试图去吃,发现旁边有人在吃,3不能吃。等待旁边人吃完4试图去吃,发现旁边有人吃,4不能吃。等待旁边人吃完0吃完,放下筷子。4发现旁边筷子没人吃,拿起筷子去吃。2吃完,放下筷子。1发现旁边筷子没人用,拿起筷子去吃。0再一次试图去吃,发现旁边有人在吃,0不能吃,等待旁边人吃完。4吃完,放下筷子。3发现旁边筷子没人用,拿起筷子去吃。2再一次试图去吃,发现旁边有人在吃,2不能吃,等待旁边人吃完。1吃完,放下筷子。0发现旁边筷子没人用,拿起筷子去吃。4试图再一次吃,发现旁边有人在吃,4不能吃,等待旁边人吃完。3吃完,放下筷子。2发现旁边筷子没人用,拿起筷子去吃。1试图再一次吃,发现旁边有人在吃,1不能吃,等待旁边人吃完。0吃完,放下筷子。4发现旁边筷子没人用,拿起筷子去吃。3试图再一次吃,发现旁边有人在吃,1不能吃,等待旁边人吃完。2吃完,放下筷子。1发现旁边筷子没人用,拿起筷子去吃。4吃完,放下筷子。3发现旁边筷子没人用,拿起筷子去吃。1吃完,放下筷子。3吃完,放下筷子。程序结果分析:开始时,五人同时试图吃,同时只有0,和2能吃,其他在等待。当有人放下筷子时,在等待的人立即有一人可以进餐。直到没人都吃过两次以后,子进程全部结束,父进程结束。附录:程序源代码#include<sys/types.h>#include<unistd.h>#include<sys/wait.h>#include<stdio.h>#include<sys/ipc.h>#include<sys/sem.h>#include<stdlib.h>#include<errno.h>#defineN5//哲学家个数#defineLEFT(i+N-1)%N#defineRIGHT(i+1)%N#defineTHINKING0#defineHUNGRY1#defineEATING2structstate{ intbuf[N];//用于保存哲学家状态结构};unionsemun{//用于semctl的参数的结构 intval; structsemid_ds*buf; ushort*array;}argument;intnewshm()//新建共享内存大小为sizeof(structstate){ intshmid; shmid=shmget(IPC_PRIVATE,sizeof(structstate),IPC_CREAT); if(shmid==-1) printf("newshmerror\n"); returnshmid;}char*getshm(intshmid)//获得共享内存映射的指针{ char*ptr=NULL; ptr=shmat(shmid,(void*)0,0); if(ptr==(void*)-1) printf("getshmerror"); returnptr;}voidtest(intsemid,inti,intshmid){ structstate*t=(structstate*)getshm(shmid); if(t->buf[i]==HUNGRY&&t->buf[LEFT]!=EATING&&t->buf[RIGHT]!=EATING) { t->buf[i]=EATING; structsembufsop={i,1,SEM_UNDO}; semop(semid,&sop,1); }}voidtake_forks(intsemid,inti,intshmid){ printf("%dtrytotaketheforks\n",i); structsembufsop={5,-1,SEM_UNDO};//p共享内存信号量 semop(semid,&sop,1); staticstructstate*sta; sta=(structstate*)getshm(shmid); sta->buf[i]=HUNGRY; test(semid,i,shmid);//判断是否能吃 structsembufsop1={5,1,SEM_UNDO};//v共享内存信号量 semop(semid,&sop1,1); structsembufsop2={i,-1,SEM_UNDO};//p对应哲学家信号量 semop(semid,&sop2,1); printf("%dhastakentheforks\n",i);}voidput_forks(intsemid,inti,intshmid){ printf("%dhasputtheforks\n",i); structsembufsop={5,-1,SEM_UNDO};//p共享内存信号量 semop(semid,&sop,1); staticstructstate*sta; sta=(structstate*)getshm(shmid); sta->buf[i]=THINKING; test(semid,LEFT,shmid); test(semid,RIGHT,shmid); structsembufsop1={5,1,SEM_UNDO};//v共享内存信号量 semop(semid,&sop1,1);}voidprint(inti)//打印状态函数{ switch(i) { case2: printf("eating\n"); break; case1: printf("hungry\n"); break; case0: printf("thinking\n"); break; }}intmain(){ structstate*sta; intsemid,numsems=6; intpc,pr; intshmid; inti,j; char*shm; staticstructstate*t; semid=semget(IPC_PRIVATE,numsems,IPC_CREAT|0666);//创建六个信号量,最后一个5用于互斥共享内存中的数据 if(semid<0) { printf("createsemaphorefailed"); exit(-1); } else{ printf("sussesscreatesemaphore\n"); } argument.val=0; for(i=0;i<N;i++)//初始化信号量0-4为0 { if(semctl(semid,i,SETVAL,argument)<0) { printf("cannotsetsemaphorevalue.\n"); //exit(-1); } else { printf("Semaphoreinitialized\n"); } } argument.val=1;//初始化共享内存信号量为1 if(semctl(semid,5,SETVAL,argument)<0) { printf("cannotsetsemaphorevalue.\n"); //exit(-1); } else { printf("Semaphoreinitialized\n"); } shmid=newshm();//初始化共享内存中哲学家状态为THINKING sta=(structstate*)getshm(shmid); for(i=0;i<N;i++) { sta->buf[i]=THINKING; } for(j=0;j<N;j++)//创建子进程 { pc=fork(); if(pc==0||pc==-1)//如果是子进程,跳出循环,防止子进程继续创建子进程 break; } if(pc<0) printf("error!"); elseif(pc==0)//子进程 { intz=0; while(z<2)//吃两次 { t=(structs

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论