基于消息队列的进程间通信的设计_第1页
基于消息队列的进程间通信的设计_第2页
基于消息队列的进程间通信的设计_第3页
基于消息队列的进程间通信的设计_第4页
基于消息队列的进程间通信的设计_第5页
已阅读5页,还剩5页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、武汉理工大学<<操作系统>>课程设计说明书学 号: 0120610340701课 程 设 计题 目基于消息队列的进程间通信的设计学 院计算机科学与技术专 业计算机科学与技术班 级计算机0607姓 名张辉艺指导教师罗芳2009年1月10日课程设计任务书学生姓名: 张辉艺 专业班级: 计算机0607 指导教师: 罗芳 工作单位: 计算机科学与技术学院 题 目: 基于消息队列的进程间通信的设计 初始条件:1预备内容:阅读linux系统的msg.c等源码文件,熟悉linux系统的消息通信机制;2实践准备:掌握一种计算机高级语言的使用。要求完成的主要任务: (包括课程设计工作量及

2、其技术要求,以及说明书撰写等具体要求)1消息的创建、发送和接收: 发送进程直接将消息挂接在接收进程的消息缓冲队列上,接收进程从消息缓冲队列中得到消息; 使用系统调用:msgget( ),msgsnd( ),msgrcv( )及msgctl( )编制一长度为1K的消息的发送和接收的程序; 分析程序,说明msgget( ),msgsnd( ),msgrcv( )及msgctl( )分别在程序中起什么作用,并解释其各个参数的含义。2设计报告内容应说明: 课程设计目的与功能; 需求分析,数据结构或模块说明(功能与框图); 源程序的主要部分; 运行结果与运行情况分析; 自我评价与总结:i)你认为你完成的

3、设计哪些地方做得比较好或比较出色;ii)什么地方做得不太好,以后如何改正;iii)从本设计得到的收获(在编写,调试,执行过程中的经验和教训);iv)完成本题是否有其他的其他方法(如果有,简要说明该方法);时间安排:设计安排一周:周1、周2:完成程序分析及设计。周2、周3:完成程序调试及测试。周4、周5:撰写课程设计报告。指导教师签名: 年 月 日系主任(或责任教师)签名: 年 月 日1. 设计目的与功能1.1设计目的通过设计和调试一个基于消息的通讯系统,来实现进程之间的直接或间接通讯,使学生对进程间的通讯机制、进程间的同步机制有一个深入的理解。该系统可用于E-MAIL的设计。 1.2设计功能

4、系统调用msgget()创建一消息获取消息的描述符并进行初始化,再调用msgsnd()向指定的消息队列发送一个消息, msgrcv()指定的消息队列中接收指定类型的消息,最后再调用msgctl()来显示或修改消息里的属性.2. 需求分析,数据结构或模块说明(功能与框图);2.1需求分析在LINUX环境下安装了GCC编译器,还需LINUX相关的系统调用.系统调用格式 msgget(key,flag)该函数使用头文件如下:#include<sys/types.h>#include<sys/ipc.h>#include<sys/msg.h>key_t key;in

5、t flag;参数定义:key是用户指定的消息队列的名字;flag是用户设置的标志和访问方式。如 IPC_CREAT |0400 是否该队列已被创建。无则创建,是则打开;IPC_EXCL |0400 是否该队列的创建应是互斥的。msgqid 是该系统调用返回的描述符,失败则返回-1。其功能是:创建一个消息,获得一个消息的描述符。核心将搜索消息队列头表,确定是否有指定名字的消息队列。若无,核心将分配一新的消息队列头,并对它进行初始化,然后给用户返回一个消息队列描述符,否则它只是检查消息队列的许可权便返回。 系统调用格式: msgsnd(msgqid,msgp,size,flag)该函数使用头文件

6、如下:#include <sys/types.h>#include <sys/ipc.h>#include <sys/msg.h>参数定义: int msgqid,size,flag;struct msgbuf * msgp;其中msgqid是返回消息队列的描述符;msgp是指向用户消息缓冲区的一个结构体指针。缓冲区中包括消息类型和消息正文,即 long mtype; /*消息类型*/ char mtext ; /*消息的文本*/ size指示由msgp指向的数据结构中字符数组的长度;即消息的长度。这个数组的最大值由MSG-MAX( )系统可调用参数来确定。

7、flag规定当核心用尽内部缓冲空间时应执行的动作:进程是等待,还是立即返回。若在标志flag中未设置IPC_NOWAIT位,则当该消息队列中的字节数超过最大值时,或系统范围的消息数超过某一最大值时,调用msgsnd进程睡眠。若是设置IPC_NOWAIT,则在此情况下,msgsnd立即返回。对于msgsnd( ),核心须完成以下工作:(1)对消息队列的描述符和许可权及消息长度等进行检查。若合法才继续执行,否则返回;(2)核心为消息分配消息数据区。将用户消息缓冲区中的消息正文,拷贝到消息数据区;(3)分配消息首部,并将它链入消息队列的末尾。在消息首部中须填写消息类型、消息大小和指向消息数据区的指针

8、等数据;(4)修改消息队列头中的数据,如队列中的消息数、字节总数等。最后,唤醒等待消息的进程。系统调用格式: msgrcv(msgqid,msgp,size,type,flag)本函数使用的头文件如下:#include <sys/types.h>#include <sys/ipc.h>#include <sys/msg.h>参数定义: int msgrcv(msgqid,msgp,size,type,flag) int msgqid,size,flag; struct msgbuf *msgp; long type;其中,msgqid,msgp,size,f

9、lag与msgsnd中的对应参数相似,type是规定要读的消息类型,flag规定倘若该队列无消息,核心应做的操作。如此时设置了IPC_NOWAIT标志,则立即返回,若在flag中设置了MS_NOERROR,且所接收的消息大于size,则核心截断所接收的消息。对于msgrcv系统调用,核心须完成下述工作:(1)对消息队列的描述符和许可权等进行检查。若合法,就往下执行;否则返回;(2)根据type的不同分成三种情况处理:type=0,接收该队列的第一个消息,并将它返回给调用者;type为正整数,接收类型type的第一个消息;type为负整数,接收小于等于type绝对值的最低类型的第一个消息。(3)

10、当所返回消息大小等于或小于用户的请求时,核心便将消息正文拷贝到用户区,并从消息队列中删除此消息,然后唤醒睡眠的发送进程。但如果消息长度比用户要求的大时,则做出错返回。2.2数据结构和模块说明(功能与框图)每个消息队列都有一个msqid_ds结构与其关联:struct msgqid_ds struct ipc_perm msg_perm; /*许可权结构*/ short pad17; /*由系统使用*/ ushort msg_qnum; /*队列上消息数*/ ushort msg_qbytes; /*队列上最大字节数*/ ushort msg_lspid; /*最后发送消息的PID*/ usho

11、rt msg_lrpid; /*最后接收消息的PID*/ time_t msg_stime; /*最后发送消息的时间*/ time_t msg_rtime; /*最后接收消息的时间*/ time_t msg_ctime; /*最后更改时间*/ ;struct ipc_perm ushort uid; /*当前用户*/ ushort gid; /*当前进程组*/ ushort cuid; /*创建用户*/ ushort cgid; /*创建进程组*/ ushort mode; /*存取许可权*/ short pid1; long pad2; /*由系统使用*/ msgp是指向用户消息缓冲区的一个

12、结构体指针。缓冲区中包括消息类型和消息正文即 long mtype; /*消息类型*/ char mtext ; /*消息的文本*/ void msg_stat(int,struct msqid_ds ); /*自定义显示消息内容*/获得或设置消息队列属性框图:获得或设置消息队列属性框图:3. 源程序的主要部分#include <sys/types.h> /系统调用相关头文件#include <sys/msg.h>#include <unistd.h>#include<stdio.h>void msg_stat(int,struct msqid_

13、ds ); /自定义显示队列属性函数main()key_t key; int msgid;int reval;struct msgsbuf /定义发送消息结构体 int mtype; char mtext1; msg_sbuf;struct msgmbuf /定义接收消息结构体 int mtype; char mtext10; msg_rbuf;struct msqid_ds msg_ginfo; char* msgpath="/root/Desktop/Linux"key=ftok(msgpath,'a');/创建一个消息,创建成功则返回消息描述符,创建失

14、败则返回-1msgid=msgget(key,IPC_CREAT | IPC_EXCL | 00666); if(msgid=-1) /测试消息创建是否成功 printf("msg create errorn"); return;msg_ginfo.msg_qbytes=1024; /设计消息队列上最大字节数msg_ginfo.msg_perm.uid=1; /设计当前用户名msg_ginfo.msg_perm.gid=2; /设计当前进程组reval=msgctl(msgid,IPC_SET,&msg_ginfo); /设置上面消息队列属性if(reval=-1)

15、 /测试设置是否成功 printf("msg set info errorn"); return;msg_stat(msgid,msg_ginfo); /调用自定义函数,验证设置消息队列属性msg_sbuf.mtype=10; /消息类型msg_sbuf.mtext0='a' /消息的文本/*发送一消息*/reval=msgsnd(msgid,&msg_sbuf,sizeof(msg_sbuf.mtext),IPC_NOWAIT);if(reval=-1) /测试发送是否成功 printf("message send errorn"

16、;);msg_stat(msgid,msg_ginfo); /发送一个消息后,输出消息队列属性/*接受消息*/reval=msgrcv(msgid,&msg_rbuf,4,10,IPC_NOWAIT|MSG_NOERROR);if(reval=-1) /测试接受消息是否成功 printf("read msg errorn");else printf("read from msg queue %d bytesn",reval); /接受成功后打印消息大小msg_stat(msgid,msg_ginfo); /从消息队列中读出消息后,输出消息队列属性

17、reval=msgctl(msgid,IPC_RMID,NULL);/删除消息队列if(reval=-1) /测试删除是否成功 printf("unlink msg queue errorn"); return;void msg_stat(int msgid,struct msqid_ds msg_info) /显示消息队列属性函数定义int reval;sleep(1);/只是为了后面输出时间的方便reval=msgctl(msgid,IPC_STAT,&msg_info); /查询消息队列属性if(reval=-1) printf("get msg i

18、nfo errorn"); return;printf("n");/消息队列中消息总大小printf("current number of bytes on queue is %dn",msg_info.msg_cbytes);/显示消息数printf("number of messages in queue is %dn",msg_info.msg_qnum);/每个消息队列的容量(字节数)都有限制MSGMNB,值的大小因系统而异。在创建新的消息队列时,这里为我们设计的1024printf("max number

19、 of bytes on queue is %dn",msg_info.msg_qbytes);/最后发送消息的进程号printf("pid of last msgsnd is %dn",msg_info.msg_lspid);/最后接收消息的进程号printf("pid of last msgrcv is %dn",msg_info.msg_lrpid);/最后发送消息的时间printf("last msgsnd time is %s", ctime(&(msg_info.msg_stime);/最后接收消息的时间

20、printf("last msgrcv time is %s", ctime(&(msg_info.msg_rtime);/最后更改时间printf("last change time is %s", ctime(&(msg_info.msg_ctime);printf("msg uid is %dn",msg_info.msg_perm.uid);/ 当前用户,我们设为1printf("msg gid is %dn",msg_info.msg_perm.gid); /当前进程组,我们设为24.运行

21、结果与运行情况分析4.1运行结果rootlocalhost Linux# gcc -o a a.crootlocalhost Linux# ./acurrent number of bytes on queue is 0number of messages in queue is 0max number of bytes on queue is 1024pid of last msgsnd is 0pid of last msgrcv is 0last msgsnd time is Thu Jan 1 08:00:00 1970last msgrcv time is Thu Jan 1 08:

22、00:00 1970last change time is Thu Jan 8 18:40:05 2009msg uid is 1msg gid is 2current number of bytes on queue is 1 /消息队列中消息总大小number of messages in queue is 1 / 消息数max number of bytes on queue is 1024 /消息队列的容量pid of last msgsnd is 3164 /消息的进程号pid of last msgrcv is 0last msgsnd time is Thu Jan 8 18:4

23、0:06 2009last msgrcv time is Thu Jan 1 08:00:00 1970last change time is Thu Jan 8 18:40:05 2009 /更改时间msg uid is 1 /当前用户msg gid is 2 /当前进程组read from msg queue 1 bytes /消息大小current number of bytes on queue is 0number of messages in queue is 0max number of bytes on queue is 1024pid of last msgsnd is 3164pid of last msgrcv is 3164last msgsnd time is Thu Jan 8 18:40:06 2009last msgrcv time is Thu Jan 8 18:40:07 2009last change time is Thu Jan 8 18:40:05 2009msg uid is 1msg gid is 24.2运行情况分析: 首先创建两个结构体来储存消息,调用msgget()创建一消息获得一个消息的描述符,再调用msgctl()更改消息队列的相关属性,比如设计每个消息队列的容量为1024,设计当前用户名为1等等.用自定义函数ms

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论