进程地消息通信带问题详解版Word文档下载推荐.docx

上传人:b****6 文档编号:18801899 上传时间:2023-01-01 格式:DOCX 页数:14 大小:101.81KB
下载 相关 举报
进程地消息通信带问题详解版Word文档下载推荐.docx_第1页
第1页 / 共14页
进程地消息通信带问题详解版Word文档下载推荐.docx_第2页
第2页 / 共14页
进程地消息通信带问题详解版Word文档下载推荐.docx_第3页
第3页 / 共14页
进程地消息通信带问题详解版Word文档下载推荐.docx_第4页
第4页 / 共14页
进程地消息通信带问题详解版Word文档下载推荐.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

进程地消息通信带问题详解版Word文档下载推荐.docx

《进程地消息通信带问题详解版Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《进程地消息通信带问题详解版Word文档下载推荐.docx(14页珍藏版)》请在冰豆网上搜索。

进程地消息通信带问题详解版Word文档下载推荐.docx

5.实验环境(硬件环境、软件环境):

(1)硬件环境:

IntelPentiumIII以上CPU,128MB以上存,2GB以上硬盘

(2)软件环境:

linux操作系统。

6.预备知识

(1)msgget()系统调用:

头文件#include<

sys/msg.h>

函数原型intmsgget(key_tkey,intflag);

功能:

创建消息队列,或返回与key对应的队列描述符。

成功返回消息描述符,失败则返回-1。

参数:

key是通信双方约定的队列关键字,为长整型数。

flag是访问控制命令,它的低9位为访问权限(代表用户、组用户、其他用户的读、写、执行访问权),其它位为队列建立方式。

(例:

rwxrwx---:

111111000)

(2)msgsnd()系统调用:

函数原型intmsgsnd(intid,structmsgbuf*msgp,intsize,intflag);

发送一个消息。

成功返回0,失败返回-1。

id是队列描述符。

msgp是用户定义的缓冲区。

size是消息长度。

flag是操作行为,若(flag&

IPC_NOWAIT)为真,调用进程立即返回;

若(flag&

IPC_NOWAIT)为假,调用进程阻塞,直到消息被发送出去或队列描述符被删除或收到中断信号为止。

缓冲区结构定义如下:

structmsgbuf{longmtype;

charmtext[n];

};

(3)msgrcv()系统调用:

函数原型intmsgrcv(intid,structmsgbuf*msgp,intsize,inttype,intflag);

接收一个消息。

成功返回消息正文长度,失败返回-1。

size是要接收的消息长度。

type是消息类型,若type为0则接收队列中的第一个消息,若type为正则接收类型为type的第一个消息。

flag是操作行为,若(flag&

IPC_NOWAIT)为真,调用进程立即返回。

IPC_NOWAIT)为假,调用进程睡眠,直到接收到消息为止。

(4)msgctl()系统调用:

函数原型intmsgctl(intid,intcmd,structmsgid_ds*buf);

查询消息队列描述符状态,或设置描述符状态,或删除描述符。

cmd是命令类型,若cmd为IPC_STAT,队列id的消息队列头结构读入buf中;

若cmd为IPC_SET,把buf所指向的信息复制到id的消息队列头结构中。

若cmd为IPC_RMID,删除id的消息队列。

Buf为消息队列头结构msgid_ds指针。

(linuxIPC

wenku.baidu./link?

url=NtXNw0BBI7lTg09Gt7Vy_IrwPRP0XyD5n1-s3ZQV-gP7iHN_ndEBOnrA5fYVNOA3wGqnwoahUWnBNkHUeQUrzIdSIsg8uiV0DWlZFHzOn4K)

7.实验容及步骤:

(1)任务描述:

使用系统调用msgget()、msgsnd()、msgrcv()、msgctl(),编写消息发送和接收程序。

要求消息的长度为1KB。

(2)程序设计过程:

先定义消息结构,

structmsgbuf{

longmtype;

charmtext[n];

};

用这个结构定义消息缓冲全局变量msg。

定义消息队列描述符msgqid。

约定队列关键字为75。

创建两个子进程client和server。

Client使用msgget()创建消息队列,使用msgsnd()发送10条消息。

Server使用msgget()获取消息队列描述符,然后用msgrcv()接收消息,完毕后删除队列描述符。

为了清楚地显示Client发送的是哪条消息,每发送一条消息,打印消息号(消息类型),Sever每收到一条消息,也打印消息类型。

设计收发方式。

Client每发送一条,Sever就接收一条。

/*收发方式:

Client()每发送一条消息,Server()就接收一条*/

/*此方法不能保证一定能同步。

对于不同速度的机器,如果没有其他耗时的进程,可以调整sleep的时间值而获得同步。

*/

//msg.c

#include<

stdio.h>

sys/types.h>

sys/ipc.h>

#defineMSGKEY75/*通信双方约定的队列关键字*/

structmsgform/*消息结构*/

{longmtype;

/*消息类型*/

charmtext[1030];

/*消息正文*/

}msg;

intmsgqid;

/*消息队列描述符*/

voidClient()

{inti;

/*局部变量i,消息类型(表示第几条消息)*/

msgqid=msgget(MSGKEY,0777);

/*创建消息队列,访问权限为777*/

for(i=10;

i>

=1;

i--)

{msg.mtype=i;

/*指定消息类型*/

printf("

(client%d)sent.\n"

i);

/*打印消息类型*/

msgsnd(msgqid,&

msg,1024,0);

/*发送消息msg到msgqid消息队列,可以先把消息正文放到msg.mtext中*/

sleep

(1);

/*使进程挂起1秒。

等待接收进程接收。

比较加上这一句和不加这一句的结果*/

}

exit(0);

}

voidServer()

{/*获得关键字对应的消息队列描述符*/

msgqid=msgget(MSGKEY,0777|IPC_CREAT);

do{

msgrcv(msgqid,&

msg,1030,0,0);

/*从msgqid队列接收消息msg*/

(server%d)received.\n"

msg.mtype);

}while(msg.mtype!

=1);

/*消息类型为1时,释放队列*/

msgctl(msgqid,IPC_RMID,0);

/*删除消息队列*/

voidmain()

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

/*创建子进程;

如果创建失败,执行空语句*/

if(!

i)Server();

/*如果i=0,在子进程中,运行Server*/

else/*否则,在父进程中*/

{while((i=fork())==-1);

/*继续创建子进程*/

i)Client();

/*如果i=0,在子进程中,运行Client*/

wait(0);

/*等待子进程结束*/

/*等待子进程结束*/

注:

IPC进程间通信(Inter-ProcessCommunication)就是指多个进程之间相互通信,交换信息的方法。

.cnblogs./liugf05/archive/2012/07/05/2578356.html

(3)上机操作

创建msg.c源文件,编译gcc–omsgmsg.c,运行./msg

观察屏幕,记录结果。

简答:

程序中有,sleep

(1);

比较加上这一句和不加这一句的结果*/,试分析为什么会有这样的运行结果差异。

 

(4)课堂练习

(1)修改上述程序,让Client向Server发送一个字符串“Themessagehereisjustajoke.”。

Server收到消息后打印出来。

参考答案:

//msg2.c

charmtext[1024];

{msg.mtype=1;

strcpy(msg.mtext,"

Themessagehereisjustajoke."

);

printf("

(client1)sent.\n"

msg,strlen(msg.mtext),0);

/*发送消息msg到msgqid消息队列,可以先把消息正文放到msg.mtext中,strlen(msg.mtext)*/

msgrcv(msgqid,&

msg,1024,0,0);

(server1)received.\n"

%s\n"

msg.mtext);

msgctl(msgqid,IPC_RMID,0);

exit(0);

/*创建子进程*/

/*子进程Server*/

else

/*子进程Client*/

(5)思考:

1、进程的消息传递机制和全局变量是一个概念吗?

消息是通过全局变量进行传递的吗?

{printf("

starcopy\n"

endcopy\n"

{

stardisplay\n"

done!

1.在client里面改变了msg.mtext,但是server里面printf出来却什么也没有,说明全局变量不可在进程间传递信息。

{sleep

(1);

clientrunning!

\n"

sleep

(2);

{

inti;

2.在主函数里面改变全局变量是可以传递消息的,因为这是父进程,server是子进程,子进程继承父进程的全部代码和资源。

3.换个位置又不行了哦,想想是为什么!

有没有晕了呢!

i){

Client();

}/*子进程Client*/

简单的说,不同的进程使用的存空间是不共用的,全局变量只是在同一个进程所占用的存空间中是全局变量,而其他的进程空间是根本看不到这个变量的。

父子进程不共享数据空间、堆、和栈。

所以不存在共享全局变量。

进程间只能IPC。

2、修改上述程序,让Client向Server发送两个字符串“Themessagehereisjustajoke.”。

效果图如下。

{msgqid=msgget(MSGKEY,0777);

//消息1发送

msg.mtype=1;

Thankyou."

//消息2发送

msg.mtype=2;

(client2)sent.\n"

//接收消息1

msg,1024,1,0);

//接收消息2

msg,1024,2,0);

(server2)received.\n"

/*消息类型为2时,释放队列*/

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

当前位置:首页 > 外语学习 > 法语学习

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

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