操作系统实验报告
实验四、进程通信(二)
                      ——消息通信
一、实验目的
1)加深对管道通信的了解
2)掌握利用管道进行通信的程序设计
3)了解共享内存通信的程序设计方法
4)了解和熟悉Linux支持的共享存储区机制
二、实验内容
任务:
1)每个同学登陆两个窗口,先在一个窗口中运行程序1(或者只登陆一个窗口,先在该窗口中以后台方式运行程序1),用ipcs命令查看系统中消息队列的情况,然后在另一个窗口中运行程序2,观察程序的运行结果并分析。运行结束后可以用ctrl+c结束程序1的运行,再次用ipcs命令观察系统中消息队列的情况。
2)使用系统调用msgget()msgsnd()msgrev()msgctl()编制一长度为1K的消息的发送和接收程序。
①为了便于操作和观察结果,用一个程序作为“引子”,先后fork()两个子进程,SERVERCLIENT,进行通信。
SERVER端建立一个Key为学号末3位的消息队列,等待其他进程发来的消息。当遇到类型为1的消息,则作为结束信号,取消该队列,并退出SERVERSERVER每接收到一个消息后显示一句“(server)received”
CLIENT端使用key为学号末3位的消息队列,先后发送类型从101的消息,然后退出。最后的一个消息,即是SERVER端需要的结束信号。CLIENT每发送一条消息后显示一句“(client)sent”
进程间通信 共享内存④父进程在SERVERCLIENT均退出后结束。
三、代码及运行结果分析
1)每个同学登陆两个窗口,先在一个窗口中运行程序1(或者只登陆一个窗口,先在该窗口中以后台方式运行程序1),用ipcs命令查看系统中消息队列的情况,然后在另一个窗口中运行程序2,观察程序的运行结果并分析。运行结束后可以用ctrl+c结束程序1的运行,再次用ipcs命令观察系统中消息队列的情况
先在一个窗口中运行程序1
程序1实验代码:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#define MSGKEY 208  /*在实际实验过程中,为了避免每个同学建立的消息队列关键字一样而相互干扰,关键字请用学号末3位*/
struct msgform
  {
        long mtype;
        char mtext [256];
  }msg;
int msgqid;
main ()
{
  int i ,pid, *pint;
  extern cleanup();
  for (i=0;i<20;i++)/*软中断处理*/
    signal (i,cleanup);
  msgqid = msgget (MSGKEY,0777|IPC_CREAT);/*建立与顾客进程相同的消息队列*/
for (;;)
      {
      msgrcv (msgqid ,&msg,256,1,0);/*接收来自顾客进程的消息*/
      pint=(int * ) msg. mtext;
      pid = * pint;
      printf ("server:receive from pid %d\n",pid);
      pe=pid;
      *pint=getpid();
      msgsnd (msgqid,&msg ,sizeof (int) ,0) ;/*发送应答消息*/
      }
  }
cleanup()
{
  msgctl (msgqid ,IPC_RMID,0);
  exit();
}
运行结果:
ipcs命令查看
在另一个窗口中运行程序2
程序2实验代码:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#define MSGKEY 208  /*在实际实验过程中,为了避免每个同学建立的消息队列关键字一样而相互干扰,关键字请用学号末3位*/
struct msgform
{
  long mtype;
  char mtext [256];
};
main()
{
struct msgform msg;
int msgqid,pid, *pint;
msgqid=msgget(MSGKEY,0777);/*建立消息队列*/
pid=getpid();
pint=(int *);
*pint=pid;
pe=1;/*指定消息类型*/
msgsnd(msgqid,&msg,sizeof(int),0);/*往msgqid发送消息msg*/
msgrcv(msgqid,&msg,256,pid,0);/*接收来自服务进程的消息*/
printf("client : receive from pid%d\n",*pint);
}
运行结果:
再次用ipcs命令观察系统中消息队列的情况
分析:
调用pipe(fd);创建一个管道后,接着调用fork()函数产生两个进程,首先开始执行子进程,关闭管道出口,通过管道入口向管道中写入内容。执行if语句后,进入else语句块内开始父进程,管道入口关闭,通过管道出口端从管道中读取之前写入内容,最后输出出来
2)使用系统调用msgget()msgsnd()msgrev()msgctl()编制一长度为1K的消息的发送和接收程序。
①为了便于操作和观察结果,用一个程序作为“引子”,先后fork()两个子进程,SERVERCLIENT,进行通信。
SERVER端建立一个Key为学号末3位的消息队列,等待其他进程发来的消息。当遇到类型为1的消息,则作为结束信号,取消该队列,并退出SERVERSERVER每接收到一个消息后显示一句“(server)received”

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。