进程间基于消息队列的通信
4、msgctl用来设置和返回与msgqid相关联的参数选择项,以及用来删除消息描述符的选择项。
主要代码
注释
#include <iostream>
#include <sys/types.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#include <stdlib.h>
msgrcv(msgqid,&msg1,512,7,0);
cout<<"receive from pid2 "<<*pint1<<endl;
exit(0);
}
else
{
while((p2=fork())==-1);
if(p2==0)
{
msgqid=msgget(MSGKEY,0777|IPC_CREAT);
cout<<"process 2 id "<<*pint2<<endl;
exit(0);
}
}
wait(0);
wait(0);
}
//基本系统数据类型
//进程间通讯
//宏定义消息队列号
//创建进程P1
//建立消息队列,若存在,返回消息描述字
//得到P1进程的id号pid1
//消息msg1地址中的内容赋值给pint1
以便其他三个系统调用使用。
2、msgsnd和msgrcv分别表示发送和接收一消息。msgsnd(msgqid,msgp,msgsz,msgflg)中的msgqid是msgget返回的消息队列描述符;msgp是用户缓冲区指针;msgsz是消息正文的长度;而msgflg是同步标识,规定msgqid发送消息时是发送完毕后返回还是不等发送立即返回。
错误2:
原因:接受队列信息存放的位置与该位置的内容不匹配
改正:msgrcv(msgqid,&msg2,512,4,0);
pint2=(int*)msg2.mtext;
指导教师评语、评分
评分:
指导教师:
年月日
msgrcv(msgqid,&msg2,512,4,0);
pint2=(int*)msg2.mtext;
pid2=*pint2;
cout<<"receive from pid1 "<<pid2<<endl;
msg2.mtype=7;
*pint2=getpid();
msgsnd(msgqid,&msg2,512,0);
3、系统调用msgrev比msgsnd多一个参数msgtyp,它规定接收消息的类型。msgtyp=0时,表示接收与msgqid相关联的消息队列上的第一个消息;msgtyp>0表示接收msgqid相关联的消息队列上的第一个消息;而msgtyp<0时,则表示接收小于或等于msgtyp绝对值的最低类型的第一个消息。
(1)掌握系统调用msgget()、msgsnd()、msgrev()、msgctl()的使用方法及其功能,理解消息通信原理;
(2)系统理解linux的三种通信机制。
实现的思想、方法和技术(含数据结构、算法)
一、消息机制提供四个系统调用:
1、msgget返回一个消息描述字msgqid,msgqid指定一个消息队列
实现工具
C++
实现环境
Linux操作系统
实习内容(功能、目标)
实验目的:
系统了解linux系统的通信机构IPC,掌握IPC中消息通信机制,理解消息通信的方法及特征。
实验内容:
编写一段程序,同时父进程创建两个子进程p1和p2;并使子进程p1与子进程p2通过消息队列相互发送消息(512字节)。
实验要求:
while((p1=fork())==-1);
if(p1==0)
{
msgqid=msgget(MSGKEY,0777);
pid1=getpid();
pint1=(int*)msg1.mtext;
*pint1=pid1;
msg1.mtype=4;
msgsnd(msgqid,&msg1,512,0);
cout<<"process 1 id "<<pid1<<endl;
//建立消息队列,若存在,返回消息描述字
///收到队列号为MSGKEY的消息队列msgqid上类型为4的消息的512个字节放到地址为&msg的位置
//消息msg2地址中的内容赋值给pint1
//pid2赋值给*pint2
///输出消息的内容
//消息msg2的类型为7
//得到进程2的id号放到地址为*pint中
#include <signal.h>
#include <string>
#define MSGKEY 1002
#include<wait.h>
using namespace std;
int msgqid;
int main()
{
struct msgform msg1,msg2,m*pint1,*pint2,*pint3;
//输出p1的id号pid
//将消息msg2地址中的512个字节写入队列号为MSGKEY的消息队列msgqid上
//输出p2的id号
结果分析(含实现中出错原因分析)
实验结果:
错误1:
原因:在进程p2还没有获得队列时,无法进行通信。通信失败
改正:msgqid=msgget(MSGKEY,0777|IPC_CREAT);
//pid1赋值给*pint
//消息msg1的类型为4
//将消息msg1地址中的512个字节写入队列号为MSGKEY的消息队列msgqid上
//输出p1的id号pid
//收到队列号为MSGKEY的消息队列msgqid上类型为7的消息的512个字节放到地址为&msg1的存储空间
//输出消息的内容
//创建子进程p2