操作系统课程设计报告.docx

上传人:b****3 文档编号:4212083 上传时间:2023-05-06 格式:DOCX 页数:27 大小:215.80KB
下载 相关 举报
操作系统课程设计报告.docx_第1页
第1页 / 共27页
操作系统课程设计报告.docx_第2页
第2页 / 共27页
操作系统课程设计报告.docx_第3页
第3页 / 共27页
操作系统课程设计报告.docx_第4页
第4页 / 共27页
操作系统课程设计报告.docx_第5页
第5页 / 共27页
操作系统课程设计报告.docx_第6页
第6页 / 共27页
操作系统课程设计报告.docx_第7页
第7页 / 共27页
操作系统课程设计报告.docx_第8页
第8页 / 共27页
操作系统课程设计报告.docx_第9页
第9页 / 共27页
操作系统课程设计报告.docx_第10页
第10页 / 共27页
操作系统课程设计报告.docx_第11页
第11页 / 共27页
操作系统课程设计报告.docx_第12页
第12页 / 共27页
操作系统课程设计报告.docx_第13页
第13页 / 共27页
操作系统课程设计报告.docx_第14页
第14页 / 共27页
操作系统课程设计报告.docx_第15页
第15页 / 共27页
操作系统课程设计报告.docx_第16页
第16页 / 共27页
操作系统课程设计报告.docx_第17页
第17页 / 共27页
操作系统课程设计报告.docx_第18页
第18页 / 共27页
操作系统课程设计报告.docx_第19页
第19页 / 共27页
操作系统课程设计报告.docx_第20页
第20页 / 共27页
亲,该文档总共27页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

操作系统课程设计报告.docx

《操作系统课程设计报告.docx》由会员分享,可在线阅读,更多相关《操作系统课程设计报告.docx(27页珍藏版)》请在冰点文库上搜索。

操作系统课程设计报告.docx

操作系统课程设计报告

计算机学院

课程设计报告

课程名称操作系统课程设计

实验学期2010至2011学年,第1学期

学生姓名

专业班级

学号

指导教师

开课系计算机科学系

 

操作系统课程组制

 

《操作系统》课程设计报告

实验题目:

UNIX系统管理实践与进程控制、进程通信实现

设计时间:

2010-12-27至

2011-01-02

一、实验目的与要求

1、掌握基本的同步与互斥算法。

2、学习使用UNIX中基本的同步对象,掌握相关函数的使用方法。

3、了解UNIX中多进程的并发执行机制,实现进程的同步与互斥。

4、查阅相关资料。

5、熟悉各种命令、系统调用与实用程序。

6、按给定功能设计相关程序。

7、撰写课程设计报告。

二、实验内容

桌上有一只盘子,盘子只能放5只水果,每次只能放一只水果或取出一只水果。

爸爸专放苹果,妈妈专放橘子,儿子专等吃盘子中的橘子,女儿专等吃盘子中的苹果。

分别用P,V操作实现他们的协作行为。

三、实验设备与环境:

VirtualBox

四、设计正文(包括分析与设计思路、各模块流程图以及带注释的主要算法源码)

分析与设计思路:

首先确定设计四个信号量,分别为盘子(semid_plate),女儿(semid_daugter),儿子(semid_son)以及一个互斥信号量(semid_mutex);四个进程,分别为母亲(mother),父亲(father),女儿(daugter)以及儿子(son).父母亲相当于生产者,当盘子(容量为五)中不满时,即可放苹果或者橘子(每次只能进行一个进程,由互斥信号量控制),否则挂起等待,直到盘子中不满时;女儿和儿子相当于消费者,当女儿要吃苹果时,首先判断盘子中是否有苹果,若有,则消费,否则挂起等待,直到盘中有苹果时,儿子亦然,先判断盘子中是否有橘子,若有,则消费,否则挂起等待,直到盘中有橘子时。

程序主要分为五个部分:

control,father,mother,daugter以及son。

Control功能是:

当缓冲区已经存在时,可以根据用户要求,对其删除或者保留,以及对信号量的初始化;father的功能:

将苹果放入缓冲区,并将缓冲区可放水果个数(semid_plate)减一,同时唤醒女儿,告诉她,有苹果可吃;mother功能:

将橘子放入缓冲区,并将缓冲区可放水果个数(semid_plate)减一,同时唤醒儿子,告诉他,有橘子可吃;daugter功能:

吃盘中的一个苹果之后,将其对应信号量减一(semid_daugter),吃完之后,盘中可放的水果数加一,表明可再放一个水果;son功能:

吃盘中的一个橘子之后,将其对应信号量减一(semid_son),吃完之后,盘中可放的水果数加一,表明可再放一个水果。

(流程图见各模块中)

 

模块一:

Control

流程图

#include

#include

#include

#include

#include

#include

#defineSHMKEY9075/*共享存储区的键*/

#defineSEMKEY_SON9085

#defineSEMKEY_DAUGTER9086

#defineSEMKEY_PLATE9087

#defineSEMKEY_MUTEX9088/*信号量数组的键*//*注意:

上面的键在系统中必须唯一*/

#defineBUFF_LEN5/*缓冲区可以存放5个水果*/

#definePRODUCT_LEN32/*每种水果是一个字符串:

<=32字符*/

voidset_sembuf_struct(structsembuf*sem,intsemnum,intsemop,intsemflg)

{

/*设置信号量结构*/

sem->sem_num=semnum;

sem->sem_op=semop;

sem->sem_flg=semflg;

}

main()

{

char*addr,end;

intshmid;

intsemid_plate,semid_son,semid_daugter,semid_mutex;/*信号量id*/

structsembufsem_tmp;

/*开辟共享存储区*/

if((shmid=shmget(SHMKEY,BUFF_LEN*PRODUCT_LEN+2,0777|IPC_CREAT|IPC_EXCL))==-1)

{

if(errno==EEXIST)

{

printf("TheBufferHasExisted!

\n");

printf("DoYouWantToDeleteTheBuffer(Y=yes)?

\n====:

");

scanf("%c",&end);

if(end=='y'||end=='Y')

{

/*共享存储区、信号量并不随程序的结束而被删除,如果我们没删除的话,

可以用ipcs命令查看,用ipcrm删除

*/

/*释放缓冲区*/

shmid=shmget(SHMKEY,BUFF_LEN*PRODUCT_LEN+2,0777);

if(shmctl(shmid,IPC_RMID,0)<0)

perror("shmctl:

");

/*同时释放信号量*/

semid_mutex=semget(SEMKEY_MUTEX,1,0777);

semid_plate=semget(SEMKEY_PLATE,1,0777);

semid_son=semget(SEMKEY_SON,1,0777);

semid_daugter=semget(SEMKEY_DAUGTER,1,0777);

semctl(semid_mutex,0,IPC_RMID);

semctl(semid_plate,0,IPC_RMID);

semctl(semid_son,0,IPC_RMID);

semctl(semid_daugter,0,IPC_RMID);

}

}

else

printf("FailToCreateBuffer!

\n");

return-1;

}

addr=(char*)shmat(shmid,0,0);/*连接缓冲区*/

memset(addr,0,BUFF_LEN*PRODUCT_LEN+2);

shmdt(addr);/*离开缓冲区*/

/*创建4个信号量:

1个用于对缓冲区互斥,3个用于生产者、消费者同步*/

if((semid_mutex=semget(SEMKEY_MUTEX,1,0777|IPC_CREAT|IPC_EXCL))==-1)

{

if(errno==EEXIST)

printf("TheSEMKEY_MUTEXHasExisted!

\n");

else

printf("FailToCreateSEMKEY_MUTEX!

\n");

return-1;

}

if((semid_plate=semget(SEMKEY_PLATE,1,0777|IPC_CREAT|IPC_EXCL))==-1)

{

if(errno==EEXIST)

printf("TheSEMKEY_PLATEHasExisted!

\n");

else

printf("FailToCreateSEMKEY_PLATE!

\n");

return-1;

}

if((semid_son=semget(SEMKEY_SON,1,0777|IPC_CREAT|IPC_EXCL))==-1)

{

if(errno==EEXIST)

printf("TheSEM_SONHasExisted!

\n");

else

printf("FailToCreateSEM_SON!

\n");

return-1;

}

if((semid_daugter=semget(SEMKEY_DAUGTER,1,0777|IPC_CREAT|IPC_EXCL))==-1)

{

if(errno==EEXIST)

printf("TheSEM_DAUGTERHasExisted!

\n");

else

printf("FailToCreateSEM_DAUGTER!

\n");

return-1;

}

/*给信号量赋初值*/

set_sembuf_struct(&sem_tmp,0,BUFF_LEN,0);/*BUFF_LEN*/

semop(semid_plate,&sem_tmp,1);

set_sembuf_struct(&sem_tmp,0,0,0);/*0*/

semop(semid_son,&sem_tmp,1);

set_sembuf_struct(&sem_tmp,0,0,0);/*0*/

semop(semid_daugter,&sem_tmp,1);

set_sembuf_struct(&sem_tmp,0,1,0);/*1*/

semop(semid_mutex,&sem_tmp,1);

return0;

}

 

模块二:

father

流程图:

/*生产者:

father.c*/

#include

#include

#include

#include

#include

#include

#defineSHMKEY9075/*共享存储区的键*/

#defineSEMKEY_SON9085

#defineSEMKEY_DAUGTER9086

#defineSEMKEY_PLATE9087

#defineSEMKEY_MUTEX9088/*信号量数组的键*//*注意:

上面的键在系统中必须唯一*/

#defineBUFF_LEN5/*缓冲区可以存放5个水果*/

#definePRODUCT_LEN32/*每种水果是一个字符串:

<=32字符*/

/*下面的P,V是对系统调用的简单封装*/

intP(intsemid)

{

structsembufp_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);

}

intV(intsemid)

{

structsembufv_buf;/*structsembuf参见课件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;/*共享存储区地址*/

unsignedcharin;/*生产者存放产品的指针:

它的值存放在全局缓冲区第一个字节*/

charproduct[128]="apple";/*事实只使用32B,128为了避免屏幕输入超过32*/

intshmid;/*共享存储区id*/

intsemid_plate,semid_son,semid_daugter,semid_mutex;/*信号量集合id*/

shmid=shmget(SHMKEY,BUFF_LEN*PRODUCT_LEN+2,0777);/*连接共享存储区:

2存放in,out的值*/

p_buffer=(char*)shmat(shmid,0,0);/*取共享存储区地址*/

semid_mutex=semget(SEMKEY_MUTEX,1,0777);/*获取全局信号量id*/

semid_plate=semget(SEMKEY_PLATE,1,0777);

semid_son=semget(SEMKEY_SON,1,0777);

semid_daugter=semget(SEMKEY_DAUGTER,1,0777);

/*进入临界区*/

P(semid_plate);/*对私有信号量作P操作*/

P(semid_mutex);/*对公有信号量作P操作*//*二者顺序不能换*/

printf("Fatherputanapple\n");

in=(unsignedchar)(*p_buffer);

strncpy(p_buffer+2+in*PRODUCT_LEN,product,PRODUCT_LEN);

in=(in+1)%BUFF_LEN;

*p_buffer=(char)in;

shmdt(p_buffer);/*离开缓冲区*/

/*离开临界区*/

V(semid_daugter);

V(semid_mutex);

 

}

模块三:

mother

流程图:

/*生产者:

mother.c*/

#include

#include

#include

#include

#include

#include

#defineSHMKEY9075/*共享存储区的键*/

#defineSEMKEY_SON9085

#defineSEMKEY_DAUGTER9086

#defineSEMKEY_PLATE9087

#defineSEMKEY_MUTEX9088/*信号量数组的键*//*注意:

上面的键在系统中必须唯一*/

#defineBUFF_LEN5/*缓冲区可以存放5个水果*/

#definePRODUCT_LEN32/*每种水果是一个字符串:

<=32字符*/

/*下面的P,V是对系统调用的简单封装*/

intP(intsemid)

{

structsembufp_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);

}

intV(intsemid)

{

structsembufv_buf;/*structsembuf参见课件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;/*共享存储区地址*/

unsignedcharin;/*生产者存放产品的指针:

它的值存放在全局缓冲区第一个字节*/

charproduct[128]="orange";/*事实只使用32B,128为了避免屏幕输入超过32*/

intshmid;/*共享存储区id*/

intsemid_plate,semid_son,semid_daugter,semid_mutex;/*信号量集合id*/

shmid=shmget(SHMKEY,BUFF_LEN*PRODUCT_LEN+2,0777);/*连接共享存储区:

2存放in,out的值*/

p_buffer=(char*)shmat(shmid,0,0);/*取共享存储区地址*/

semid_mutex=semget(SEMKEY_MUTEX,1,0777);/*获取全局信号量id*/

semid_plate=semget(SEMKEY_PLATE,1,0777);

semid_son=semget(SEMKEY_SON,1,0777);

semid_daugter=semget(SEMKEY_DAUGTER,1,0777);

/*进入临界区*/

P(semid_plate);/*对私有信号量作P操作*/

P(semid_mutex);/*对公有信号量作P操作*//*二者顺序不能换*/

printf("Motherputanorange\n");

in=(unsignedchar)(*p_buffer);

strncpy(p_buffer+2+in*PRODUCT_LEN,product,PRODUCT_LEN);

in=(in+1)%BUFF_LEN;

*p_buffer=(char)in;

shmdt(p_buffer);/*离开缓冲区*/

/*离开临界区*/

V(semid_son);

V(semid_mutex);

}

 

模块四:

daugter

流程图:

/*消费者:

daugter.c*/

#include

#include

#include

#include

#include

#include

#defineSHMKEY9075/*共享存储区的键*/

#defineSEMKEY_SON9085

#defineSEMKEY_DAUGTER9086

#defineSEMKEY_PLATE9087

#defineSEMKEY_MUTEX9088/*信号量数组的键*//*注意:

上面的键在系统中必须唯一*/

#defineBUFF_LEN5/*缓冲区可以存放5个水果*/

#definePRODUCT_LEN32/*每种水果是一个字符串:

<=32字符*/

/*下面的P,V是对系统调用的简单封装*/

intP(intsemid)

{

structsembufp_buf;/*structsembuf参见课件ppt*/

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);

}

intV(intsemid)

{

structsembufv_buf;

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;/*共享存储区地址*/

unsignedcharout;/*消费者取出产品的指针:

它的值存放在全局缓冲区第二个字节*/

charproduct[33];/*它的数据从缓冲区中取*/

intshmid;/*共享存储区id*/

intsemid_plate,semid_son,semid_daugter,semid_mutex;/*信号量集合id*/

shmid=shmget(SHMKEY,BUFF_LEN*PRODUCT_LEN+2,0777);/*连接共享存储区:

2存放in,out的值*/

p_buffer=(char*)shmat(shmid,0,0);/*取共享存储区地址*/

semid_mutex=semget(SEMKEY_MUTEX,1,0777);/*获取全局信号量id*/

semid_plate=semget(SEMKEY_PLATE,1,0777);

semid_son=semget(SEMKEY_SON,1,0777);

semid_daugter=semget(SEMKEY_DAUGTER,1,0777);

/*进入临界区*/

P(semid_daugter);/*对私有信号量作P操作*/

P(semid_mutex);/*对公有信号量作P操作*//*二者顺序不能换*/

out=(unsignedchar)(*p_buffer);

strcpy(product,p_buffer+1+out*PRODUCT_LEN);

out=(out+1)%BUFF_LEN;

*p_buffer=(char)out;

p_buffer--;

shmdt(p_buffer);/*离开缓冲区*/

/*离开临界区*/

V(semid_plate);

V(semid_mutex);

/*吃掉水果:

在屏幕上输出*/

printf("Daugtereatsanapple\n");

}

模块五:

son

流程图:

/*消费者:

son.c*/

#include

#include

#include

#include

#include

#include

#d

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 法律文书 > 判决书

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2