ImageVerifierCode 换一换
格式:DOCX , 页数:12 ,大小:135.89KB ,
资源ID:678885      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/678885.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(操作系统实验 消息的发送与接收.docx)为本站会员(b****4)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

操作系统实验 消息的发送与接收.docx

1、操作系统实验 消息的发送与接收操作系统实验 消息的发送与接收MSG一、实验目的1、了解什么是消息 2、熟悉消息传送的机理。二、实验内容消息的创建、发送和接收。使用系统调用msgget( ),msgsnd( ),msgrev( ),及msgctl( )编制一长度为k的消息发送和接收的程序三、实验内容指导提示(一)、什么是消息消息(message)是一个格式化的可变长的信息单元。消息机制允许由一个进程给其它任意的进程发送一个消息。当一个进程收到多个消息时,可将它们排成一个消息队列。消息使用二种重要的数据结构:一是消息首部,其中记录了一些与消息有关的信息,如消息数据的字节数;二个消息队列头表,其每一

2、表项是作为一个消息队列的消息头,记录了消息队列的有关信息。1、消息机制的数据结构(1)消息首部记录一些与消息有关的信息,如消息的类型、大小、指向消息数据区的指针、消息队列的链接指针等。(2)消息队列头表其每一项作为一个消息队列的消息头,记录IPC_NOWAIT位,则当该消息队列中的字节数超过最大值时,或系统范围的消息数超过某一最大值时,调用msgsnd进程睡眠。若是设置IPC_NOWAIT,则在此情况下,msgsnd立即返回。对于msgsnd( ),核心须完成以下工作:(1)对消息队列的描述符和许可权及消息长度等进行检查。若合法才继续执行,否则返回;(2)核心为消息分配消息数据区。将用户消息缓

3、冲区中的消息正文,拷贝到消息数据区;(3)分配消息首部,并将它链入消息队列的末尾。在消息首部中须填写消息类型、消息大小和指向消息数据区的指针等数据;(4)修改消息队列头中的数据,如队列中的消息数、字节总数等。最后,唤醒等待消息的进程。3. msgrcv( )接受一消息。从指定的消息队列中接收指定类型的消息。系统调用格式: msgrcv(msgqid,msgp,size,type,flag)本函数使用的头文件如下: #include #include #include 参数定义: int msgrcv(msgqid,msgp,size,type,flag) int msgqid,size,fla

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

5、整数,接收类型type的第一个消息;type为负整数,接收小于等于type绝对值的最低类型的第一个消息。(3)当所返回消息大小等于或小于用户的请求时,核心便将消息正文拷贝到用户区,并从消息队列中删除此消息,然后唤醒睡眠的发送进程。但如果消息长度比用户要求的大时,则做出错返回。4. msgctl( )消息队列的操纵。读取消息队列的状态信息并进行修改,如查询消息队列描述符、修改它的许可权及删除该队列等。系统调用格式: msgctl(msgqid,cmd,buf);本函数使用的头文件如下: #include #include #include 参数定义: int msgctl(msgqid,cmd,

6、buf); int msgqid,cmd; struct msgqid_ds *buf;其中,函数调用成功时返回0,不成功则返回-1。buf是用户缓冲区地址,供用户存放控制参数和查询结果;cmd是规定的命令。命令可分三类:(1)IPC_STAT。查询有关消息队列情况的命令。如查询队列中的消息数目、队列中的最大字节数、最后一个发送消息的进程标识符、发送时间等;(2)IPC_SET。按buf指向的结构中的值,设置和改变有关消息队列属性的命令。如改变消息队列的用户标识符、消息队列的许可权等;(3)IPC_RMID。消除消息队列的标识符。msgqid_ds 结构定义如下:struct msgqid_d

7、s struct ipc_perm msg_perm; /*许可权结构*/ short pad17; /*由系统使用*/ ushort msg_qnum; /*队列上消息数*/ ushort msg_qbytes; /*队列上最大字节数*/ ushort msg_lspid; /*最后发送消息的PID*/ ushort msg_lrpid; /*最后接收消息的PID*/ time_t msg_stime; /*最后发送消息的时间*/ time_t msg_rtime; /*最后接收消息的时间*/ time_t msg_ctime; /*最后更改时间*/ ;struct ipc_perm ush

8、ort uid; /*当前用户*/ ushort gid; /*当前进程组*/ ushort cuid; /*创建用户*/ ushort cgid; /*创建进程组*/ ushort mode; /*存取许可权*/ short pid1; long pad2; /*由系统使用*/ (三)、参考程序1、client.c#include #include #include #define MSGKEY 75struct msgform long mtype; char mtext1000;msg;int msgqid;void client() int i;msgqid=msgget(MSGKEY

9、,0777); /*打开75#消息队列*/for(i=10;i=1;i-) msg.mtype=i;printf(“(client)sentn”);msgsnd(msgqid,&msg,1024,0); /*发送消息*/exit(0);main( ) client( );2、server.c#include #include #include #define MSGKEY 75struct msgform long mtype; char mtext1000;msg;int msgqid;void server( ) msgqid=msgget(MSGKEY,0777|IPC_CREAT);

10、/*创建75#消息队列*/do msgrcv(msgqid,&msg,1030,0,0); /*接收消息*/ printf(“(server)receivedn”);while(msg.mtype!=1);msgctl(msgqid,IPC_RMID,0); /*删除消息队列,归还资源*/exit(0);main( ) server( );(四)、程序说明1、为了便于操作和观察结果,编制二个程序client.c和server.c,分别用于消息的发送与接收。2、server建立一个 Key 为75的消息队列,等待其它进程发来的消息。当遇到类型为1的消息,则作为结束信号,取消该队列,并退出serv

11、er。server每接收到一个消息后显示一句“(server)received。”3、client使用 key为75的消息队列,先后发送类型从10到1的消息,然后退出。最后一个消息,即是 server端需要的结束信号。client 每发送一条消息后显示一句 “(client)sent”。4、注意: 二个程序分别编辑、编译为client与server。执行:./server&ipcs -q./client。(五)、运行结果从理想的结果来说,应当是每当client发送一个消息后,server接收该消息,client再发送下一条。也就是说“(client)sent”和 “(server)receiv

12、ed”的字样应该在屏幕上交替出现。实际的结果大多是,先由client发送了两条消息,然后server接收一条消息。此后client 、server交替发送和接收消息。最后server一次接收两条消息。client 和server 分别发送和接收了10条消息,与预期设想一致。(六)、思考message的传送和控制并不保证完全同步,当一个程序不在激活状态的时候,它完全可能继续睡眠,造成了上面的现象,在多次send message 后才recieve message。这一点有助于理解消息传送的实现机理。【附加:共享存储区的创建,附接和断接来实现进程通信留给有时间的同学看 使用系统调用shmget()

13、,sgmat(),smgdt(),shmctl()编制一个与上述功能相同的程序. (1)为了便于操作 和观察结果,用一个 程序为“引子”,先后fork( )两个子进程,SERVER 和 CLIENT,进行通信。 (2)SERVER端建立一个KEY为75的共享区,并将第一个字节置为-1.作为数据空的标志.等待其他进程发来的消息.当该字节的值发生变化时,表示收到了该消息,进行处理.然后再次把它 的值设为-1.如果遇到的值为0,则视为结束信号,取消该队列,并退出SERVER.SERVER每接 收到一次数据后显示”(server)received”. (3)CLIENT端建立一个为75的共享区,当共享

14、取得第一个字节为-1时, Server端空闲,可发送 请求. CLIENT 随即填入9到0.期间等待Server端再次空闲.进行完这些操作后, CLIENT 退出. CLIENT每发送一次数据后显示”(client)sent”. (4)父进程在SERVER和CLIENT均退出后结束.#include#include#include#define SHMKEY 75 /*定义共享区关键词*/int shmid,i;int *addr;void * shmat();/*如果去掉这行,看看运行结果,分析为什么*/ CLIENT() int i; shmid=shmget(SHMKEY,1024, 0777|IPC_CREAT); /*获取共享区,长度1024,关键词SHMKEY*/ addr=shmat(shmid,0,0); /*共享区起始地址为addr*/ for(i=9;i=0;i-) while(*addr!= -1); printf(client)sentn); /*打印(client)sent*/ *addr=i; /*把i赋给addr*/

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

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