




已阅读5页,还剩15页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
江苏大学计算机学院课程设计报告江苏大学计算机学院课程设计报告课程名称 操作系统课程设计 实验学期 2010至2011学年,第 1 学期学生姓名 周勇 专业班级 计算机0801 学 号 3080602049 指导教师 詹 永 照 开 课 系 计算机科学系 操作系统课程组制操作系统课程设计报告实验题目:Linux系统管理实践与进程控制、进程通信实现设计时间:2010-12-27至 2011-01-02一、 实验目的与要求1、 掌握基本的同步与互斥算法。2、 学习使用Linux中基本的同步对象,掌握相关函数的使用方法。3、 了解Linux中多进程的并发执行机制,实现进程的同步与互斥。4、 查阅相关资料。5、 熟悉各种命令、系统调用与实用程序。6、 按给定功能设计相关程序。7、 撰写课程设计报告。二、 实验内容桌上有一只盘子,盘子只能放5只水果,每次只能放一只水果或取出一只水果。爸爸专放苹果,妈妈专放橘子,儿子专等吃盘子中的橘子,女儿专等吃盘子中的苹果。分别用P,V操作实现他们的协作行为。三、 实验设备与环境实验设备:虚拟机运行平台:Linux 语言:c四、 设计正文(包括分析与设计思路、各模块流程图以及带注释的 主要算法源码)设计思路:设计4个进程,分别是父亲进程,母亲进程,儿子进程,女儿进程。设置一个缓冲区,用来放水果,长度为5.所以设置一个公有信号量mutex,以限制他们对缓冲区的放和取,初值为1.另外设置私有信号S2,S1.以控制儿子是否可以取橘子吃,女儿是否可以取苹果吃。初值都为0.还要设置一个信号量empty,控制父亲跟母亲之间的同步,初值为5。表示现在缓冲区有5个空位可以放。各模块流程图:Conntrol.c开辟共享存储区设置信号量结构创建信号量:1个用于对缓冲区互斥,3个用于父亲、母亲、儿子、女儿同步释放缓冲区,同时释放信号量给信号量赋初值Father.c 和 mother.c执行P(semid_empty)将进程插入到等待信号量mutex的进程队列中。并且阻塞该进程。empty0将进程插入到等待信号量empty的进程队列中。并且阻塞该进程。执行P(semid_mutex)mutex 0 y n y n n 母亲放一个橘子父亲放一个苹果 离开缓冲区执行V(semid_s1)唤醒等待S1进程队列的一个进程。 执行V(semid_mutex),允许母亲放水果,子女取水果。Son.c 执行P(semid_s2)将进程插入到等待信号量mutex的进程队列中。并且阻塞该进程。S20将进程插入到等待信号量s2的进程队列中。并且阻塞该进程。执行P(semid_mutex)mutex 0执行V(semid_empty)唤醒等待empty进程队列的一个进程。 执行V(semid_mutex),允许父母放水果,女儿取苹果。儿子吃一个橘子离开缓冲区 y n y ndaughter.c 执行P(semid_s1)将进程插入到等待信号量mutex的进程队列中。并且阻塞该进程。S10将进程插入到等待信号量s1的进程队列中。并且阻塞该进程。执行P(semid_mutex)mutex 0执行V(semid_empty)唤醒等待empty进程队列的一个进程。 执行V(semid_mutex),允许父母放水果,儿子取橘子。女儿吃一个苹果离开缓冲区带注释的 主要算法源码:1.Conntrol.c#include #include #include #include #include #include #include #include #define SHMKEY 9075 /*共享存储区的键*/#define SEMKEY_EMPTY 9085#define SEMKEY_S1 9086#define SEMKEY_S2 9087#define SEMKEY_MUTEX 9088 /*信号量数组的键*/#define BUFF_LEN 5 /*缓冲区可以存放个水果*/#define FRUIT_LEN 12 /*水果用字符串代替*/void set_sembuf_struct(struct sembuf *sem,int semnum, int semop,int semflg) /* 设置信号量结构*/ sem-sem_num=semnum; sem-sem_op=semop; sem-sem_flg=semflg; main() char *addr, end; int shmid; unsigned char in; int semid_empty, semid_s1,semid_s2, semid_mutex;/*信号量id*/ struct sembuf sem_tmp; /*开辟共享存储区*/ if (shmid = shmget(SHMKEY, BUFF_LEN * FRUIT_LEN, 0777|IPC_CREAT|IPC_EXCL) = -1) if (errno = EEXIST) printf(The Buffer Has Existed!n); printf(Do You Want To Delete The Buffer(Y = yes)?n=:); scanf(%c, &end); if(end = y | end = Y) /* 共享存储区、信号量并不随程序的结束而被删除,如果我们没删除的话, 可以用ipcs命令查看,用ipcrm删除 */ /*释放缓冲区*/ shmid = shmget(SHMKEY, BUFF_LEN * FRUIT_LEN, 0777); if (shmctl(shmid,IPC_RMID,0) 0) perror(shmctl:); /*同时释放信号量*/ semid_mutex = semget(SEMKEY_MUTEX,1, 0777); semid_empty = semget(SEMKEY_EMPTY,1, 0777); semid_s1 = semget(SEMKEY_S1,1, 0777); semid_s2 = semget(SEMKEY_S2,1, 0777); semctl(semid_mutex,0,IPC_RMID); semctl(semid_empty,0,IPC_RMID); semctl(semid_s1,0,IPC_RMID); semctl(semid_s2,0,IPC_RMID); else printf(Fail To Create Buffer!n); return -1; addr = (char*)shmat(shmid, 0, 0);/*连接缓冲区*/ memset(addr, 0, BUFF_LEN * FRUIT_LEN); shmdt(addr); /*离开缓冲区*/ /*创建信号量:1个用于对缓冲区互斥,3个用于父亲、母亲、儿子、女儿同步*/ if(semid_mutex = semget(SEMKEY_MUTEX,1, 0777|IPC_CREAT|IPC_EXCL)=-1) if (errno = EEXIST) printf(The SEMKEY_MUTEX Has Existed!n); else printf(Fail To Create SEMKEY_MUTEX!n); return -1; if(semid_s1 = semget(SEMKEY_S1,1, 0777|IPC_CREAT|IPC_EXCL)=-1) if (errno = EEXIST) printf(The SEMKEY_S1 Has Existed!n); else printf(Fail To Create SEMKEY_S1!n); return -1; if(semid_s2 = semget(SEMKEY_S2,1, 0777|IPC_CREAT|IPC_EXCL)=-1) if (errno = EEXIST) printf(The SEMKEY_S2 Has Existed!n); else printf(Fail To Create SEMKEY_S2!n); return -1; if(semid_empty = semget(SEMKEY_EMPTY,1, 0777|IPC_CREAT|IPC_EXCL)=-1) if (errno = EEXIST) printf(The SEM_EMPTY Has Existed!n); else printf(Fail To Create SEM_EMPTY!n); return -1; /*给信号量赋初值*/ set_sembuf_struct(&sem_tmp, 0, BUFF_LEN, 0);/*BUFF_LEN*/ semop(semid_empty, &sem_tmp,1); set_sembuf_struct(&sem_tmp, 0, 0, 0);/*0*/ semop(semid_s1, &sem_tmp,1); set_sembuf_struct(&sem_tmp, 0, 0, 0);/*0*/ semop(semid_s2, &sem_tmp,1); set_sembuf_struct(&sem_tmp, 0, 1, 0);/*1*/ semop(semid_mutex, &sem_tmp,1); return 0;2.Father.c/*下面的P,V是对系统调用的简单封装*/int P(int semid) struct sembuf p_buf; p_buf.sem_num = 0; p_buf.sem_op = -1; p_buf.sem_flg = 0; if(semop(semid, &p_buf, 1)=-1)/*semop参见课件ppt*/ perror (p (semid) falsed); exit (1); else return (0);int V(int semid) struct sembuf v_buf;/*struct sembuf 参见课件ppt*/ v_buf.sem_num = 0; v_buf.sem_op = 1; v_buf.sem_flg = 0; if(semop(semid, &v_buf, 1)=-1) perror ( v (semid) failed); exit (1); else return (0);main() char *p_buffer;/*共享存储区地址*/ unsigned char in;/*生产者存放产品的指针:它的值存放在全局缓冲区第一个字节*/ int shmid;/*共享存储区id*/ int semid_empty, semid_s1,semid_s2, semid_mutex;/*信号量集合id*/ shmid = shmget(SHMKEY, BUFF_LEN *FRUIT_LEN, 0777);/*连接共享存储区:2 存放in,out的值*/ p_buffer = (char*)shmat(shmid, 0, 0);/*取共享存储区地址*/ semid_mutex = semget(SEMKEY_MUTEX,1, 0777);/*获取全局信号量id*/ semid_empty = semget(SEMKEY_EMPTY,1, 0777); semid_s1 = semget(SEMKEY_S1,1, 0777); semid_s2 = semget(SEMKEY_S2,1, 0777); /*进入临界区*/ P(semid_empty);/*对私有信号量作P操作*/ P(semid_mutex);/*对公有信号量作P操作*/*二者顺序不能换*/ in = (unsigned char)(*p_buffer); int j=0; for(j=0;j5;j+) if(*(p_buffer + in * FRUIT_LEN)!=apple)&(*(p_buffer + in * FRUIT_LEN)!=orange) printf(father put a apple!n); *(p_buffer + in * FRUIT_LEN)= apple; break; in = (in + 1) % BUFF_LEN; shmdt(p_buffer); /*离开缓冲区*/ /*离开临界区*/ V(semid_s1); V(semid_mutex);3.Mother.c/*下面的P,V是对系统调用的简单封装*/int P(int semid) struct sembuf p_buf; p_buf.sem_num = 0; p_buf.sem_op = -1; p_buf.sem_flg = 0; if(semop(semid, &p_buf, 1)=-1)/*semop参见课件ppt*/ perror (p (semid) falsed); exit (1); else return (0);int V(int semid) struct sembuf v_buf;/*struct sembuf 参见课件ppt*/ v_buf.sem_num = 0; v_buf.sem_op = 1; v_buf.sem_flg = 0; if(semop(semid, &v_buf, 1)=-1) perror ( v (semid) failed); exit (1); else return (0);main() char *p_buffer;/*共享存储区地址*/ unsigned char in;/*生产者存放产品的指针:它的值存放在全局缓冲区第一个字节*/ int shmid;/*共享存储区id*/ int semid_empty, semid_s1,semid_s2, semid_mutex;/*信号量集合id*/ shmid = shmget(SHMKEY, BUFF_LEN * FRUIT_LEN, 0777);/*连接共享存储区:2 存放in,out的值*/ p_buffer = (char*)shmat(shmid, 0, 0);/*取共享存储区地址*/ semid_mutex = semget(SEMKEY_MUTEX,1, 0777);/*获取全局信号量id*/ semid_empty = semget(SEMKEY_EMPTY,1, 0777); semid_s1 = semget(SEMKEY_S1,1, 0777); semid_s2 = semget(SEMKEY_S2,1, 0777); /*进入临界区*/ P(semid_empty);/*对私有信号量作P操作*/ P(semid_mutex);/*对公有信号量作P操作*/*二者顺序不能换*/ in = (unsigned char)(*p_buffer); int j=0; for(j=0;j5;j+) if(*(p_buffer + in * FRUIT_LEN)!=apple)&(*(p_buffer + in * FRUIT_LEN)!=orange) printf(mother put a orange!n); *(p_buffer + in * FRUIT_LEN)= orange; break; in = (in + 1) % BUFF_LEN; shmdt(p_buffer); /*离开缓冲区*/ /*离开临界区*/ V(semid_s2); V(semid_mutex);4.Son.c/*下面的P,V是对系统调用的简单封装*/int P(int semid) struct sembuf p_buf; p_buf.sem_num = 0; p_buf.sem_op = -1; p_buf.sem_flg = 0; if(semop(semid, &p_buf, 1)=-1)/*semop参见课件ppt*/ perror (p (semid) falsed); exit (1); else return (0);int V(int semid) struct sembuf v_buf;/*struct sembuf 参见课件ppt*/ v_buf.sem_num = 0; v_buf.sem_op = 1; v_buf.sem_flg = 0; if(semop(semid, &v_buf, 1)=-1) perror ( v (semid) failed); exit (1); else return (0);main() char *p_buffer;/*共享存储区地址*/ unsigned char in;/*生产者存放产品的指针:它的值存放在全局缓冲区第一个字节*/ int shmid;/*共享存储区id*/ int semid_empty, semid_s1,semid_s2, semid_mutex;/*信号量集合id*/ shmid = shmget(SHMKEY, BUFF_LEN * FRUIT_LEN, 0777);/*连接共享存储区:2 存放in,out的值*/ p_buffer = (char*)shmat(shmid, 0, 0);/*取共享存储区地址*/ semid_mutex = semget(SEMKEY_MUTEX,1, 0777);/*获取全局信号量id*/ semid_empty = semget(SEMKEY_EMPTY,1, 0777); semid_s1 = semget(SEMKEY_S1,1, 0777); semid_s2 = semget(SEMKEY_S2,1, 0777); /*进入临界区*/ P(semid_s2);/*对私有信号量作P操作*/ P(semid_mutex);/*对公有信号量作P操作*/*二者顺序不能换*/ in = (unsigned char)(*p_buffer); int j=0; printf(son get a orange!n); for(j=0;j5;j+) if(*(p_buffer + in * FRUIT_LEN)=orange) *(p_buffer + in * FRUIT_LEN)=0; break; in = (in + 1) % BUFF_LEN; shmdt(p_buffer); /*离开缓冲区*/ /*离开临界区*/ V(semid_empty); V(semid_mutex);5.Daughter.c/*下面的P,V是对系统调用的简单封装*/int P(int semid) struct sembuf p_buf; p_buf.sem_num = 0; p_buf.sem_op = -1; p_buf.sem_flg = 0; if(semop(semid, &p_buf, 1)=-1)/*semop参见课件ppt*/ perror (p (semid) falsed); exit (1); else return (0);int V(int semid) struct sembuf v_buf;/*struct sembuf 参见课件ppt*/ v_buf.sem_num = 0; v_buf.sem_op = 1; v_buf.sem_flg = 0; if(semop(semid, &v_buf, 1)=-1) perror ( v (semid) failed); exit (1); else return (0);main() char *p_buffer;/*共享存储区地址*/ unsigned char in;/*生产者存放产品的指针:它的值存放在全局缓冲区第一个字节*/ int shmid;/*共享存储区id*/ int semid_empty, semid_s1,semid_s2, semid_mutex;/*信号量集合id*/ shmid = shmget(SHMKEY, BUFF_LEN * FRUIT_LEN, 0777);/*连接共享存储区:2 存放in,out的值*/ p_buffer = (char*)shmat(shmid, 0, 0);/*取共享存储区地址*/ semid_mutex = semget(SEMKEY_MUTEX,1, 0777);/*获取全局信号量id*/ semid_empty = semget(SEMKEY_EMPTY,1, 0777); semid_s1 = semget(SEMKEY_S1,1, 0777); semid_s2 = semget(SEMKEY_S2,1, 0777); /*进入临界区*/ P(semid_s1);/*对私有信号量作P操作*/ P(semid_mutex);/*对公有信号量作P操作*/*二者顺序不能换*/ in = (unsigned char)(*p_buffer); int j=0; printf(daughter get a apple!n); for(j=0;j5;j+) if(*(p_buffer + in * FRUIT_LEN)=apple) *(p_buffer + in * FRUIT_LEN)=0; break; in = (in + 1) % BUFF_LEN; shmdt(p_buffer); /*离开缓冲区*/ /*离开临界区*/ V(semid_empty); V(semid_mutex);五、 实验结果及分析放入了5个水果,在执行父亲进程,则该进程被阻塞。此时执行儿子进程,吃掉一个橘子,缓冲区空位增1,唤醒了等待中的父亲进程,此时父亲可以放入一个橘子。此时橘子被吃完,再执行儿子进程,则被阻塞。执行一次母亲进程,放入一个橘子,来唤醒儿子进程,此时刚才的儿子进程执行,吃掉一个橘子。缓冲区满,执行母亲进程,被阻塞执行儿子进程,吃掉一个橘子,此时唤醒刚才的母亲进程,放入一个橘子。女儿吃完了苹果
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 鹰潭社区送菜活动方案
- 餐吧活动优惠活动方案
- 光谱金相考试题及答案
- 高级电考试题及答案
- 干衣机培训考试题及答案
- 欢庆中秋节作文600字10篇
- 服装导购考试题及答案
- 客户需求分析与解决方案工具包
- 丰胸的考试题及答案
- 企业预算编制及成本控制指南手册
- 2025年计算机等级考试二级WPS Office高级应用与设计试题与参考答案
- 卧式椭圆封头储罐液位体积对照表
- 医院视频监控系统维保方案
- 身体素养评价指南 第2部分:儿童青少年
- 2024装修施工安全合同样本
- 人教版数学一年级上册 前后上下左右专项练习题(试题)
- 合资投资谅解备忘录书
- 粮油作物种植与管理作业指导书
- 《预防未成年人犯罪》课件(图文)
- IT项目经理招聘笔试题及解答2025年
- DB65-T 4784-2024 冰川范围调查技术规范
评论
0/150
提交评论