操作系统——实验三(进程间通信)——3.3.3

操作系统——实验三(进程间通信)——3.3.3

实验目的

1、了解linux系统中进程通信的基本原理。

2、分析进程竞争资源现象,学习解决进程互斥的方法。


3.3.3消息通信

使用系统调用msgget(),msgsnd(),msgrcv()及msgctl()编制一长度为1K的消息发送和接收的程序。

〈程序设计〉

(1)为了便于操作和观察结果,用一个程序为“引子”,先后fork()两个子进程,SERVER和CLIENT,进行通信。

(2)SERVER端建立一个Key为75的消息队列,等待其他进程发来的消息。当遇到类型为1的消息,则作为结束信号,取消该队列,并退出SERVER。SERVER每接收到一个消息后显示一句“(server)received”。

(3)CLIENT端使用Key为75的消息队列,先后发送类型从10到1的消息,然后退出。最后的一个消息,既是SERVER端需要的结束信号。CLIENT每发送一条消息后显示一句“(client)sent”。

(4)父进程在SERVER和CLIENT均退出后结束。

第一步

创建c文件夹,在它下面创建test.c文件

mkdir c
vim test.c

第二步

写入参考程序

程序

#include<stdio.h>
#include<sys/types.h>
#include<sys/msg.h>
#include<sys/ipc.h>
#define MSGKEY 75/*定义关键词MEGKEY*/
struct msgform/*消息结构*/
{
long mtype;
char mtxt[1030];/*文本长度*/
}msg;
int msgqid,i;

void CLIENT()
{
int i;
msgqid=msgget(MSGKEY,0777);
for(i=20;i>=1;i--)
{
msg.mtype=i;
printf("(client)sent\n");
msgsnd(msgqid,&msg,1024,0);/*发送消息msg入msgid消息队列*/
}
exit(0);
"c/test3.c" 45L, 769C                                        
msgsnd(msgqid,&msg,1024,0);/*发送消息msg入msgid消息队列*/
}
exit(0);
}

void SERVER()
{
msgqid=msgget(MSGKEY,0777|IPC_CREAT);/*由关键字获得消息队列*/
do
{
msgrcv(msgqid,&msg,1030,0,0);/*从队列msgid接受消息msg*/
printf("(server)receive\n");
}while(msg.mtype!=1);/*消息类型为1时,释放队列*/
msgctl(msgqid,IPC_RMID,0);//delete signal
exit(0);
}

main()
{
if(fork())
SERVER();
else
CLIENT();
wait(0);
}

记录结果

分析

message的传送和控制并不保证完全同步,当一个程序不再激活状态的时候,它完全可能继续睡眠,造成上面现象,在多次sendmessage后才receivemessage.这一点有助于理解消息转送的实现机理。

消息通信的特点:消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。消息的传递,自身就带有同步的控制.当等到消息的时候,进程进入睡眠状态,不再消耗CPU资源。(摘自实验指导书)

 

  • 7
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值