编辑模拟多进程共享临界资源.docx

上传人:b****2 文档编号:3003701 上传时间:2023-05-05 格式:DOCX 页数:27 大小:341.45KB
下载 相关 举报
编辑模拟多进程共享临界资源.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

编辑模拟多进程共享临界资源

课程设计

 

课程设计名称:

操作系统原理

专业班级:

软件1301

学生姓名:

理金龙

学号:

201316920126

指导教师:

刘於勋

课程设计时间:

2015年7月6-11日

 

软件工程专业课程设计任务书

学生姓名

理金龙

专业班级

软件1301

学号

201316920126

题目

编程模拟多进程共享临界资源

课题性质

其它

课题来源

自拟课题

指导教师

刘於勋

同组姓名

主要内容

要求产生3个进程:

1、两个进程模拟需要进入临界区的用户进程,当需要进入临界区时,显示:

“进程x请求进入临界区…”,同时向管理进程提出申请;申请返回,表示进入了临界区。

在临界区中等待一段随机时间,并显示:

“进程x正在临界区…”;当时间结束,显示:

“进程x退出临界区…”,同时向管理进程提出退出申请;当申请返回,显示:

“进程x已退出临界区。

2、一个进程作为原语的管理进程,接受其他进程的临界区进入请求:

如果允许进入,则设置相应变量,然后返回;如果不允许进入,则进入循环等待,直到允许为止;

3、对临界区的访问应遵循空闲让进、忙则等待、有限等待、让权等待的准则。

4、进程间通信可以采用信号、消息传递、管道或网络通信方式。

任务要求

 

理解多进程共享临界资源的原理,并编程实现

 

参考文献

任满杰等《操作系统原理实用教程》电子工业出版社2006

汤子瀛《计算机操作系统》(修订版)西安电子科技大学出版社2001

张尧学史美林《计算机操作系统教程》实验指导清华大学出版社2000

罗宇等《操作系统课程设计》机械工业出版社2005

审查意见

指导教师签字:

教研室主任签字:

2015年7月6日

说明:

本表由指导教师填写,由教研室主任审核后下达给选题学生,装订在设计(论文)首页

信息科学与工程学院课程设计成绩评价表

课程名称:

操作系统原理

设计题目:

编程模拟多进程共享临界资源

专业:

软件工程班级:

软件1301姓名:

理金龙学号:

201316920126

序号

评审项目

分数

满分标准说明

1

内容

思路清晰,语言表达准确,概念清楚,论点正确;设计方法科学,分析归纳合理;结论严谨,设计有应用价值。

任务饱满,工作量适中

2

创新

内容新颖,设计能反映新技术,对前人工作有改进或突破,或有独特见解

3

完整性、实用性

整体构思后合理,理论依据充分,设计完整,实用性强

4

数据准确、可靠

数据准确,算法设计合理

5

规范性

设计格式、绘图、实验数据、标准的运用等符合有关标准和规定

6

纪律性

遵守课程设计纪律,听从指导教师安排,设计过程态度认真

7

答辩

准备充分,思路清晰、论点正确、对设计方案理解深入,问题回答有理有据,简明正确

总分

 

指导教师2015年7月12日

1需求分析

1、要求产生至少3个进程:

2、两个进程模拟需要进入临界区的用户进程,当需要进入临界区时,显示:

“进程x请求进入临界区…”,同时向管理进程提出申请;在临界区中等待一段随机时间,并显示:

“进程x正在临界区…”;当时间结束,显示:

“进程x退出临界区…”,同时向管理进程提出退出申请。

3、一个进程作为原语级管理进程,接受其他进程的临界区进入请求:

如果允许进入,则设置相应变量,然后返回;如果不允许进入,则进入循环等待,直到允许为止;

4、对临界区的访问应遵循空闲让进、忙则等待、有限等待、让权等待的准则。

5、进程间通信可以采用信号、消息传递、管道或网络通信方式。

2概要设计

2.1其中包含两个重要的数据结构:

2.11临界区:

Structcrform

{

Intsem;//临界区的信号量值sem

Inthead;//临界区等待队列的头,指向的是最先到的进程

Inttail;//临界区等待队列的尾,指向的是进入等待队列的进程

Intduilie[20];//存放的是等待的进程的信息,以便唤醒

}cr;

Cr.sem=1;//初始临界区信号量必须为一,因为只允许一个进程进入临界区

Cr.head=0;//初始时指向等待队列的第一个单元

Cr.tail=0;

2.12消息队列:

Structmsgform

{

Longmsgtype;//消息的类型,在取消息队列时用于区分哪些是该取的信息

Intmtext;//信息的内容,在这里是申请|退出进程的信息

};

2.2进程创建和控制:

fork()系统调用:

关键的语句:

intx,y;

while((x=fork())==-1);//创建子进程1

if(x==0)

{

//子进程1执行程序段

}

else

{

while((y=fork())==-1);

if(y==0)

{

//子进程2执行程序段

}

else

{

//父进程执行程序段

}

}

2.3设计流程图:

图1用户进程流程图

图管理进程

图3申请进入临界区处理子进程

图4申请退出处理子程序

3运行环境

3.1linux操作系统

3.2Gcc编译器

4开发工具和编程语言

4.1开发工具:

Gcc编译器

4.2编程语言:

C语言

5详细设计

子函数一:

voidinto()//申请进入临界区

{

structmsgformmsg;

key_thh=ftok("OSP.c",1);

intmsgqid=msgget(hh,0666|IPC_CREAT);

cr.sem--;//一旦申请进入临界区就得减1

msgrcv(msgqid,&msg,4,1,0);//接收消息--申请进入进程发送的类型为1

msg.msgtype=(long)msg.mtext;//并把接收到的消息内容作为回馈消息的消息类型

if(cr.sem>=0)//判断此时进程的状态,sem>=0可以获得临界区

{

if(msg.mtext==3)

printf("进程1:

进入临界区\n");

else

printf("进程2:

进入临界区\n");

msg.mtext=1;//现在允许进入,发送内容为1的消息给申请进程

msgsnd(msgqid,&msg,sizeof(int),0);

}

Else//到等待队列

{

if(msg.mtext==3)

printf("进程1:

进入等待队列\n");

else

printf("进程2:

进入等待队列\n");

cr.duilie[cr.tail]=msg.mtext;

cr.tail++;

if(cr.tail==20)

cr.tail=0;

msg.mtext=-1;

msgsnd(msgqid,&msg,sizeof(int),0);//若临界区忙,发送进入等待队列的消息给申请进入的进程

}

子函数二:

voidout()//申请退出临界区

{

structmsgformmsg;

key_thh=ftok("OSP.c",1);

intmsgqid=msgget(hh,0666|IPC_CREAT);

msgrcv(msgqid,&msg,4,2,0);//从消息队列上取下申请退出的消息

cr.sem++;

if(cr.tail!

=cr.head)//查看等待队列中是否有等待进入临界区的队列

{

//有则唤醒等待队列中等待的进程,并允许申请退出的进程退出

if(msg.mtext==3)

printf("进程1:

退出临界区\n");

else

printf("进程2:

退出临界区\n");

msg.msgtype=msg.mtext;

msg.mtext=0;

msgsnd(msgqid,&msg,sizeof(int),0);

intpid2=cr.duilie[cr.head];

cr.head++;

if(cr.head==20)

cr.head=0;

msg.mtext=1;

msg.msgtype=pid2;

if(pid2==3)

printf("进程1:

进入临界区\n");

else

printf("进程2:

进入临界区\n");

msgsnd(msgqid,&msg,sizeof(int),0);

}

else//如果等待队列上没有等待进入临界区的进程,直接向申请退出的进程发送消息,允许退出

{

if(msg.mtext==3)

printf("进程1:

退出临界区\n");

else

printf("进程2:

退出临界区\n");

msg.msgtype=msg.mtext;

msg.mtext=0;

msgsnd(msgqid,&msg,sizeof(int),0);

}

}

6调试分析

在作这个课题过程中遇到了主要的这样几个问题:

◆消息队列不能正常使用

错误原因1:

消息队列没有建立成功

解决办法:

在用消息队列之初先删除这个队列,然后再建立使用

错误原因2:

取到的结果总出现错误,没有统一的消息类型

解决办法:

定制统一的消息类型规则,依照规则使用消息类型

错误原因3:

进程需要的消息已经被取走,使得进程停留在取消息这一步不向下执行

解决办法:

是程序逻辑上的问题,仔细查看程序流程并操控好使得可以处于正常逻辑

◆申请到临界区退出临界区显示滞后(如有时会显示“进程一获得临界区”然后“进程二退出临界区”)

错误原因:

在管理进程中已经将临界区状态修改为空闲,却没有显示哪个进程退出临界区,这个退出的信息必须等到子进程上cpu时才会显示出来,而这中间有别的进程上cpu执行申请的操作,就会获得临界区,就会显示“进程获得临界区”,在此后退出临界区的进程才上cpu显示“退出临界区”。

解决办法:

将显示放到管理进程中,一旦有进程获得临界区或者退出临界区就做出显示。

7测试结果

测试数据:

1,0;1,2

测试截图:

图5开始界面

图6主程序运行界面

图7输入1,暂停运行

图8输入0,程序继续运行

图9输入2,程序退出运行

 

参考文献

[1]任满杰等《操作系统原理实用教程》电子工业出版社2006

[2]汤子瀛《计算机操作系统》(修订版)西安电子科技大学出版社2001

[3]张尧学史美林《计算机操作系统教程》实验指导清华大学出版社2000

[4]罗宇等《操作系统课程设计》机械工业出版社2005

[5]赛奎春、张雨编著,《VisualC++工程应用与项目实践》,海洋出版社,2005.1

心得体会

这次操作系统课设给了我很大的启发和提高。

一直以来自己我的编程基础不太好,常出现逻辑混乱,不注重细节问题,在这门课中我有了更深的理解;科学是不允许错误的,需要认真严谨的态度。

也正是因为如此我才有了进步。

理论联系实际,总会有更深刻的收获,通过这样的实际思考,动手修改操作,对理论有了深层次的理解,更加证实了理论,打消了心中不切实际的一些想法。

慢慢的会形成自己的一个实际经验,为日后的工作学习打下心里和知识上的基础。

小学期的课程真是紧张而又充实,确实是收获很多,心中也增加了几分自信,对未来的工作有更大的信息。

程序源代码(工程)

第一部分:

OSP.c

#include

#include

#include

#include

#include

#include

#include

#include"ran.h"

#defineMSGKEY898989

structcrform

{

intsem;

inthead;

inttail;

intduilie[20];

}cr;

 

structmsgform

{

longmsgtype;

intmtext;

};

 

voidinto();

voidout();

intmain(void){

puts("***********************提示信息***********************\n");

puts("在程序运行过程中:

\n");

puts("-------输入0继续运行程序\n");

puts("-------输入1暂停运行程序\n");

puts("-------输入2退出程序\n");

puts("*****************************************************\n");

intppid=getpid();

cr.sem=1;

cr.head=0;

cr.tail=0;

structShMe{

intnum;

intflags;

intp1;

intp2;

};

intshmid=shmget(IPC_PRIVATE,1024,0666|IPC_CREAT);

if(shmid==-1){

printf("共享内存区创建错误-----\n");

exit(0);

}

 

pid_tid=fork();

if(id<0){

printf("新进程创建错误!

2秒后自动退出。

\n");

sleep

(2);

exit(0);

}elseif(id==0){

pid_tid2=fork();

if(id2<0){

printf("新进程创建错误!

2秒后自动退出。

\n");

sleep

(2);

exit(0);

}elseif(id2==0){

structmsgformmsg;

key_thh=ftok("OSP.c",1);

intmsgqid=msgget(hh,0666|IPC_CREAT);

 

structShMe*addr;

addr=(structShMe*)shmat(shmid,0,0);

if(addr==(structShMe*)-1)

printf("映射内存错误1------\n");

intflags=0;

flags=addr->flags;

(*addr).p1=getpid();

while(flags==1||flags==0){

if(flags==0){

intq=10;

msg.mtext=3;

msg.msgtype=1;

printf("进程1:

申请进入临界区\n");

msgsnd(msgqid,&msg,sizeof(int),0);

kill(ppid,10);

while(q>0)

{

msgrcv(msgqid,&msg,sizeof(int),3,0);

intm=msg.mtext;

if(m==1)

{

printf("进程1:

进入共享内存区\n");

intny=addr->num;

intdg=rannum();

intuh=0;

for(uh=0;uh

ny++;

}

ny=ny%(99999-10000+1)+10000;

(*addr).num=ny;

msg.msgtype=2;

msg.mtext=3;

printf("进程1:

申请退出临界区\n");

msgsnd(msgqid,&msg,sizeof(int),0);

kill(ppid,12);

continue;

}

else

{

if(m==-1)

{

q--;

}

else

{

if(m==0)

{

intbb=rannum()%5;

sleep(bb);

flags=addr->flags;

break;

}

}

}

}

}else{

intbb=rannum()%5;

sleep(bb);

flags=addr->flags;

}

}

}else{

structmsgformmsg;

key_thh=ftok("OSP.c",1);

intmsgqid=msgget(hh,0666|IPC_CREAT);

structShMe*addr;

addr=(structShMe*)shmat(shmid,0,0);

if(addr==(structShMe*)-1)

printf("映射内存错误1------\n");

intflags=0;

flags=addr->flags;

(*addr).p2=getpid();

while(flags==1||flags==0){

if(flags==0){

intq=10;

msg.mtext=4;

msg.msgtype=1;

printf("进程2:

申请进入临界区\n");

msgsnd(msgqid,&msg,sizeof(int),0);

kill(ppid,10);

while(q>0)

{

msgrcv(msgqid,&msg,sizeof(int),4,0);

intm=msg.mtext;

if(m==1)

{

printf("进程2:

进入临界区\n");

intny=addr->num;

intdg=rannum();

intuh=0;

for(uh=0;uh

ny++;

}

ny=ny%(99999-10000+1)+10000;

(*addr).num=ny;

msg.msgtype=2;

msg.mtext=4;

printf("进程2:

申请退出临界区\n");

msgsnd(msgqid,&msg,sizeof(int),0);

kill(ppid,12);

continue;

}

else

{

if(m==-1)

{

q--;

}

else

{

if(m==0)

{

intbb=rannum()%5;

sleep(bb);

flags=addr->flags;

break;

}

}

}

}

}else{

intbb=rannum()%5;

sleep(bb);

flags=addr->flags;

}

}

}

}else{

 

key_thh=ftok("OSP.c",1);

intmsgqid=msgget(hh,0666|IPC_CREAT);

 

structShMe*addr;

addr=(structShMe*)shmat(shmid,0,0);

if(addr==(structShMe*)-1)

printf("映射内存错误3------\n");

(*addr).num=999;

(*addr).flags=0;

intflags=0;

signal(10,into);

signal(12,out);

scanf("%d",&flags);

while(flags==0||flags==1){

(*addr).flags=flags;

scanf("%d",&flags);

}

if(flags==2){

(*addr).flags=flags;

}

wait(addr->p1);

wait(addr->p2);

if(shmdt(addr)==-1)

printf("共享内存与控制进程断开错误........\n");

if(shmctl(shmid,IPC_RMID,NULL)==-1)

printf("shmctldeleteerror\n");

msgctl(msgqid,IPC_RMID,0);

printf("************》》》程序退出\n");

}

returnEXIT_SUCCESS;

}

voidinto()

{

structmsgformmsg;

key_thh=ftok("OSP.c",1);

 

intmsgqid=msgget(hh,0666|IPC_CREAT);

cr.sem--;

msgrcv(msgqid,&msg,4,1,0);

msg.msgtype=(long)msg.mtext;

if(cr.sem>=0)

{

if(msg.mtext==3)

printf("进程1:

进入临界区\n");

else

printf("进程2:

进入临界区\n");

msg.mtext=1;

msgsnd(msgqid,&msg,sizeof(int),0);

}

else

{

if(msg.mtext==3)

printf("进程1:

进入等待队列\n");

else

printf("进程2:

进入等待队列\n");

cr.duilie[cr.tail]=msg.mtext;

cr.tail++;

if(cr.tail==20)

cr.tail=0;

msg.mtext=-1;

msgsnd(msgqid,&msg,sizeof(int),0);

}

}

voidout()

{

structmsgformmsg;

key_thh=ftok("OSP.c",1);

intmsgqid=msgget(hh,0666|IPC_CREAT);

msgrcv(msgqid,&msg,4,2,0);

cr.sem++;

if(cr.tail!

=cr.head)

{

if(msg.mtext==3)

printf("进程1:

退出临界区\n");

else

printf("进程2:

退出临界区\n");

msg.msgtype=msg.mtext;

msg.mtext=0;

msgsnd(msgqi

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

当前位置:首页 > 工程科技 > 能源化工

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

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