操作系统作业2--进程和进程通信

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

实验二进程和进程通信实验报告仅供参考仅供参考!(一)实验目的通过使用进程和进程通信方面的系统调用的,加深理解有关进程方面的基本概念。通过实验对进程有进一步的感性认识,掌握系统V的IPC机制。(二)实验题目1.设计一个程序,创建一个子进程,使父子进程合作,协调地完成某一功能。要求在该程序中还要使用进程的睡眠、进程图象改换、父进程等待子进程终止、信号的设置与传送(包括信号处理程序)、子进程的终止等有关进程的系统调用。2.利用UNIX的消息通信机制、共享内存机制(要用信号灯实施进程间的同步和互斥)实现两个进程间的数据通信。具体的通信数据可从一个文件读出,接收方进程可将收到的数据写入一个新文件,以便能判断数据传送的正确性(对文件操不熟悉的同学可不必通过读写文件,只要键盘输入和输出至屏幕进行比较即可)。(蓝字部分对一般同学不作要求)(三)实验报告要求要求在实验室当场调试完成,经老师检查通过,登记,实验报告可免做。对于因特殊情况,不能到实验室上机的同学,可在自己的Linux机器上机,但要求写实验报告,包括题目、数据结构的说明,画出程序框图,在源程序中加入注释,说明程序的测试方法和测试结果,以及实验总结或体会。在实验报告中要有一幅Linux系统运行的截图,截图中要注释实验者的姓名或学号。实验报告不要做压缩文件。为了截图,可以建立以学号为用户名的帐号,或在命令行中输入姓名或学号(会显示出错,没有关系),或在程序加入注释,再对其截图。至少要完成一道实验题。一、运行程序(一)、数据结构说明和程序框图1、数据结构说明main()函数:子进程的创建都是在main()函数里面;signalfun(),是信号SIGUSR1对应的处理函数;writetofile函数,是对一个文件写如一定的内容的函数;readfromfile,是从一个文件里面读取内容的函数。2、程序框图如下:(二)、源程序1、父子进程程序#includesys/types.h#includesignal.hmain(){intpid,status=1;voidfunc();signal(SIGUSR1,func);/*预置信号处理程序,将SIGUSR1设置为func函数的功能*/while((pid=fork())==-1);if(pid){/*父进程*/printf(Itistheparentprocess.\n);开始Fork()输入字符,并写入文件结束YesNo子进程读取父进程写入的文件,并处理,处理后写回文件子进程结束后,从文件读取子进程处理结果,显示结果向子进程传送信号,并阻塞本身,等待子进程结束初始化处理后是数据字符?进程图像转换NoYesprintf(Parent:willsendsignal.\n);kill(pid,SIGUSR1);/*发送信号,即发送执行func函数的信息*/pid=wait(&status);/*父进程等待子进程终止*/printf(Childprocess%d,status=%d\n,pid,status);}else{/*子进程*/sleep(2);/*等待接受信号*/printf(Itisthechildprocess.\n);printf(Child:signalisreceived.\n);execvp(pwd,(char*)0);/*映像改换,显示当前工作区,exevcp不用给出具体路径,(char*)0指向pwd命令*/printf(execlerror.\n);/*映像改换失败*/exit(2);}printf(Parentprocessfinish.\n);}voidfunc(){system(date);}2、消息通信机制/*msgcom.h*/#includeerrno.h#includesys/types.h#includesys/ipc.h#includesys/msg.h#defineMSGKEY5678structmsgtype{longmtype;inttext;};#includemsgcom.hmain(){/*请求进程*/structmsgtypebuf;intqid,pid;qid=msgget(MSGKEY,IPC_CREAT|0666);/*MSGKEY为约定的消息队列关键字,访问控制权限为0666*/buf.mtype=1;/*请求进程发送消息标识为1*/buf.text=pid=getpid();/*请求进程发送消息内容为进程标识*/msgsnd(qid,&buf,sizeof(buf.text),IPC_NOWAIT|04000);/*发送消息正文长度为buf的大小*/msgrcv(qid,&buf,512,pid,MSG_NOERROR);/*指定接收mtype=pid的信息,即请求进程发送给服务器处理后的信息*/printf(Requestreceivedamassagsfromserver,typeis:%d\n,buf.mtype);}#includemsgcom.hmain(){/*服务器进程*/structmsgtypebuf;intqid;if((qid=msgget(MSGKEY,IPC_CREAT|0666))==-1)return(-1);/*出错处理*/while(1){msgrcv(qid,&buf,512,1,MSG_NOERROR);/*接收所有请求进程发送的消息*/printf(Serverreceivearequestfromprocess%d\n,buf.text);buf.mtype=buf.text;/*将请求进程的标识数作为mtype的值,以便于请求进程识别*/msgsnd(qid,&buf,sizeof(int),IPC_NOWAIT|04000);/*将消息发送给请求进程*/}}3、共享内存机制#includesys/types.h#includesys/ipc.h#includesys/sem.h#includesys/shm.h#includestdio.h#defineSHMKEY18001/*共享内存关键字*/#defineSHMKEY218002#defineSIZE1024/*共享内存长度*/#defineSEMKEY119001/*信号灯组1关键字*/#defineSEMKEY219002/*信号灯组2关键字*/#defineSEMKEY319003/*信号灯组3关键字*/staticvoidsemcall(sid,op)intsid,op;{structsembufsb;sb.sem_num=0;/*信号灯编号0*/sb.sem_op=op;/*信号灯操作数加1或减1*/sb.sem_flg=0;/*操作标志*/if(semop(sid,&sb,1)==-1)perror(semop);/*出错处理*/};intcreatsem(key)/*信号灯组创建及初始化程序*/key_tkey;{intsid;unionsemun{/*如sem.h中已定义,则省略*/intval;structsemid_ds*buf;ushort*array;}arg;if((sid=semget(key,1,0666|IPC_CREAT))==-1)/*创建1个关键字为1的信号灯组,访问控制权限为0666*/perror(semget);/*出错处理*/arg.val=1;/*初值为1*/if(semctl(sid,0,SETVAL,arg)==-1)/*将信号灯组的第一个信号灯的初值置1*/perror(semctl);/*出错处理*/return(sid);}voidP(sid)intsid;{semcall(sid,-1);/*对关键字为sid信号灯组值减1,相当于wait*/}voidV(sid)intsid;{semcall(sid,1);/*对关键字为sid信号灯组值加1,相当于signal*/}main(){char*segaddr,*segaddr2;intsegid,segid2,sid1,sid2,sid3;if((segid=shmget(SHMKEY,SIZE,IPC_CREAT|0666))==-1)/*创建共享内存段*/perror(shmget);/*出错处理*/if((segid2=shmget(SHMKEY2,SIZE,IPC_CREAT|0666))==-1)/*创建共享内存段2*/perror(shmget);/*出错处理*/segaddr=shmat(segid,0,0);/*将共享内存映射到进程数据空间*/segaddr2=shmat(segid2,0,0);/*将共享内存2映射到进程数据空间*/sid1=creatsem(SEMKEY1);/*创建三个信号灯,初值为1*/sid2=creatsem(SEMKEY2);sid3=creatsem(SEMKEY3);P(sid2);/*置信号灯2值为0,表示缓冲区1空*/P(sid3);/*置信号灯3值为0,表示缓冲区2空*/if(!fork()){if(!fork()){while(1){/*子进程的子进程,接收和输出*/P(sid3);printf(ReceivedfromParent:%s\n,segaddr2);printf(ReceivedfromGrandparent:%s\n,segaddr);V(sid1);}}while(1){/*子进程,输入和存储*/P(sid2);scanf(%s,segaddr2);V(sid3);}}while(1){/*父进程,输入和存储*/P(sid1);scanf(%s,segaddr);V(sid2);}}(三)测试方法:黑箱测试法二、测试结果1、父子进程通信2、消息通信1)请求进程2)服务器进程3、共享内存三、实验总结或体会进程间的通信的方法有很多种,可以通过管道、消息、信号、共享内存等等一些方法,来实现进程的协作,从而实现计算机间的协作,进而完成复杂的任务。而且对于这些方法,只有通过实践应用过,才能够有更深刻的理解,才能更好的掌握这些方法并加以利用。仅供参考仅供参考!

1 / 7
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功