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

上传人:b****6 文档编号:8667469 上传时间:2023-02-01 格式:DOCX 页数:18 大小:51.65KB
下载 相关 举报
操作系统课程设计报告.docx_第1页
第1页 / 共18页
操作系统课程设计报告.docx_第2页
第2页 / 共18页
操作系统课程设计报告.docx_第3页
第3页 / 共18页
操作系统课程设计报告.docx_第4页
第4页 / 共18页
操作系统课程设计报告.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

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

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

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

操作系统课程设计报告

课程设计报告

课程名称:

操作系统课程设计

 

设计题目:

进程同步P、V操作模拟—吃水果问题

学院:

信息科学与技术学院

专业:

计算机科学与技术

组别:

学生姓名:

学号:

指导教师:

一、操作系统课程设计题目

基于LINUX系统的管理实践与进程控制、进程通信的实现

进程通信题目:

桌上有一只盘子,每次只能放入3只水果。

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

利用P,V操作原理来实现爸爸、妈妈、儿子、女儿进程的同步控制,橘子用orange表示,苹果用apple表示,空用empty表示。

二、开发环境

LINUX操作系统

三、分析设计

(一)实验原理

1.原理:

parents(包括father和mother)-->|+++|(缓冲区:

存放3个水果)-->daughter和son。

  Parents和daughter、son通过共享缓冲区进行通信,信号量用于对缓冲区互斥访问、对parents和daughter、son进行同步。

2.实验过程共有五个程序:

control,father,mother,son,daughter.其中control是主控程序.

  control:

实现对缓冲区的初始化,要求第一个执行的程序,且只需要执行一次。

father:

把一个苹果放入缓冲区中:

输入一个字符串(32字节以内)。

mother:

把一个橘子放入缓冲区当中:

输入一个字符串(32字节以内)。

son:

从缓冲区取出一个橘子:

屏幕上输出一个字符串。

daughter:

从缓冲区取出一个苹果:

屏幕上输出一个字符串。

3.注意:

信号量、共享缓冲区都是系统资源,其总个数有上限。

每个资源的id号在系统中唯一,并且系统不会主动释放它们,所以要小心使用,及时释放资源。

 本程序中:

control在执行一次后(成功执行),信号量、共享缓冲区就会分配。

如果再执行它,control会提示资源已经分配,是否要释放它们?

如果键入y(Y),则资源释放,此后执行father,mother,son,daughter都会报错。

当然也可以使用ipcsipcrm命令来查看或释放资源。

4.为了结构的清晰,程序没有多余的输入或输出。

在father,mother,son,daughter程序中适当的位置增加输出语句,和输入字符语句将程序暂停在某个位置,以观察运行的详细进程。

(二)虚拟机下linux挂载U盘

要求:

让虚拟机GuestOS(Linux)能自动识别U盘。

方法如下:

保持焦点在Linux上,插入U盘,这时宿主操作系统Windows会弹出“找到新设备的提示”,然后一步一步的点下一步,结束以后,就可以在linux使用fdisk-l/dev/sdb命令查看到/dev/sdb1。

在虚拟机识别出USB之后,用fdisk-l/dev/sdb或fdisk-l/dev/hdb查看,会看到U盘被识别为sdb1,使用mount命令挂载即可。

先在/mnt建一个新的文件夹,例如usb。

则可通过:

mount-tvfat/dev/sdb1/mnt/usb挂载上U盘

卸载使用:

umount/dev/sdb1

四、源程序

1.主控程序control.c

#include

#include

#include

#include

#include

#include

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

#defineSEMKEY_son9084

#defineSEMKEY_parents9085

#defineSEMKEY_daughter9086

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

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

#defineBUFF_LEN3/*缓冲区可以存放3个产品*/

#definePRODUCT_LEN10/*每个产品是一个字符串:

<=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_parents,semid_daughter,semid_son,semid_mutex;/*信号量id*/

structsembufsem_tmp;

/*开辟共享存储区*/

if((shmid=shmget(SHMKEY,BUFF_LEN*PRODUCT_LEN+4,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+4,0777);

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

perror("shmctl:

");

/*同时释放信号量*/

semid_mutex=semget(SEMKEY_MUTEX,1,0777);

semid_daughter=semget(SEMKEY_daughter,1,0777);

semid_parents=semget(SEMKEY_parents,1,0777);

semid_son=semget(SEMKEY_son,1,0777);

semctl(semid_mutex,0,IPC_RMID);

semctl(semid_daughter,0,IPC_RMID);

semctl(semid_parents,0,IPC_RMID);

semctl(semid_son,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);/*离开缓冲区*/

/*创建3个信号量:

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

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_daughter=semget(SEMKEY_daughter,1,0777|IPC_CREAT|IPC_EXCL))==-1)

{

if(errno==EEXIST)

printf("TheSEMKEY_daughterHasExisted!

\n");

else

printf("FailToCreateSEMKEY_daughter!

\n");

return-1;

}

if((semid_parents=semget(SEMKEY_parents,1,0777|IPC_CREAT|IPC_EXCL))==-1)

{

if(errno==EEXIST)

printf("TheSEM_parentsHasExisted!

\n");

else

printf("FailToCreateSEM_parents!

\n");

return-1;

}

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

{

if(errno==EEXIST)

printf("TheSEMKEY_sonHasExisted!

\n");

else

printf("FailToCreateSEMKEY_son!

\n");

return-1;

}

/*给信号量赋初值*/

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

semop(semid_parents,&sem_tmp,1);

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

semop(semid_daughter,&sem_tmp,1);

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

semop(semid_son,&sem_tmp,1);

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

semop(semid_mutex,&sem_tmp,1);

return0;

}

2.父亲:

father.c

#include

#include

#include

#include

#include

#include

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

#defineSEMKEY_son9084

#defineSEMKEY_parents9085

#defineSEMKEY_daughter9086

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

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

#defineBUFF_LEN3/*缓冲区可以存放3个水果*/

#definePRODUCT_LEN6/*每个产品是一个字符串:

<=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;/*生产者存放产品的指针:

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

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

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

intsemid_parents,semid_daughter,semid_mutex;/*信号量集合id*/

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

2存放in,out的值*/

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

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

semid_parents=semget(SEMKEY_parents,1,0777);

semid_daughter=semget(SEMKEY_daughter,1,0777);

/*从屏幕接收产品*/

printf("PleaseProduct(astring,length<=32B):

\n====:

");

gets(apple);/*128的意义在此,此函数不检查字符串长度*/

/*进入临界区*/

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

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

in=(unsignedchar)(*p_buffer);

strncpy(p_buffer+4+in*PRODUCT_LEN,apple,PRODUCT_LEN);

in=(in+1);

*p_buffer=(char)in;

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

/*离开临界区*/

V(semid_daughter);

V(semid_mutex);

}

3.母亲:

mother.c

#include

#include

#include

#include

#include

#include

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

#defineSEMKEY_son9084

#defineSEMKEY_parents9085

#defineSEMKEY_daughter9086

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

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

#defineBUFF_LEN3/*缓冲区可以存放3个水果*/

#definePRODUCT_LEN10/*每个产品是一个字符串:

<=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;/*生产者存放产品的指针:

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

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

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

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

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

2存放in,out的值*/

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

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

semid_parents=semget(SEMKEY_parents,1,0777);

semid_son=semget(SEMKEY_son,1,0777);

/*从屏幕接收产品*/

printf("PleaseProduct(astring,length<=32B):

\n====:

");

gets(orange);/*128的意义在此,此函数不检查字符串长度*/

/*进入临界区*/

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

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

p_buffer=p_buffer+2;

in=(unsignedchar)(*p_buffer);

strncpy(p_buffer+2+(BUFF_LEN-1)*PRODUCT_LEN-in*PRODUCT_LEN,orange,PRODUCT_LEN);

in=(in+1);

*p_buffer=(char)in;

p_buffer=p_buffer-2;

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

/*离开临界区*/

V(semid_son);

V(semid_mutex);

}

4.女儿:

daughter.c

#include

#include

#include

#include

#include

#include

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

#defineSEMKEY_son9084

#defineSEMKEY_parents9085

#defineSEMKEY_daughter9086

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

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

#defineBUFF_LEN3/*缓冲区可以存放3个水果*/

#definePRODUCT_LEN10/*每个产品是一个字符串:

<=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,in;/*消费者取出产品的指针:

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

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

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

intsemid_parents,semid_daughter,semid_mutex;/*信号量集合id*/

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

2存放in,out的值*/

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

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

semid_parents=semget(SEMKEY_parents,1,0777);

semid_daughter=semget(SEMKEY_daughter,1,0777);

/*进入临界区*/

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

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

p_buffer++;

out=(unsignedchar)(*p_buffer);

p_buffer=p_buffer-1;

in=(unsignedchar)(*p_buffer);

strcpy(apple,p_buffer+4+out*PRODUCT_LEN);

if(in==2)

{

strcpy(p_buffer+4+0*PRODUCT_LEN,p_buffer+4+1*PRODUCT_LEN);

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

当前位置:首页 > 党团工作 > 入党转正申请

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1