【操作系统】实验四:进程通信(二)【完整版实验报告】

实验四:进程通信(二)

实验目的:
学习如何利用消息缓冲队列进行进程间的通信,并加深对消息缓冲队列通信机制的理解。
实验内容:
(1) 了解系统调用msgget()、msgsnd()、msgrcv()、msgctl()的功能和实现过程。
(2) 编写一段程序,使其用消息缓冲队列来实现父进程和子进程之间的通信。

0.父进程先建立一个关键字为MSGKEY(如75)(即#define MSGKEY 75)的消息队列,然后等待接收类型为1的消息;
1.在收到请求消息后,它便显示字符串“serving for client ”和接收到的子进程的进程标识数,表示正在为子进程服务;
2.然后再向子进程发送一应答消息,该消息的类型是该子进程的进程标识数,而正文则是父进程自己的标识数。
3.子进程则向消息队列发送类型为1的消息(消息的正文为自己的进程标识数),以取得父进程的服务,并等待父进程发来的应答;然后显示字符串“receive reply from ”和接收到的父进程的标识数。
消息的结构为:
struct msgform{
long mtype; //消息类型
char mtext[1024]; //消息正文
};
思考:
(1)消息缓冲机制是否提供了发送进程和接收进程之间的同步功能?同步是如何进行的?
答:
首先进程同步的定义是:我们把异步环境下的一组并发进程因直接制约而互相发送消息、进行互相合作、互相等待,使得各进程按一定的速度执行的过程称为进程间的同步。
消息队列允许任意进程通过共享队列来进行进程间通信。并由系统调用函数来实现消息发送和接收之间的同步。从而使得用户在使用消息缓冲进行通信时不再需要考虑同步问题,使用相对方便。

(2) 消息缓冲机制有什么特点,它适合于何种场合?
答:
消息队列与管道方式的区别在于,消息队列可以实现多对多,并需要在内存中实现,而管道可以在内存或磁盘上实现。
消息队列中信息的复制需要耗费CPU时间,不适宜信息量大或频繁操作的场合。

实现代码:

#include
#include
#include
#include
#include
#include
#include
#include

#define MSGKEY 75

struct msgbuf{
     long mtype;
     char mtext[1024];
};

int main()
{
     int pid;
     int msqid;

     struct msgbuf sendermsgp,recevermsgp;
     

     msqid=msgget((key_t)MSGKEY,IPC_CREAT|0666);//create one message quence
     if(msqid<0){
          printf("wrong in function of msget\n");
          return 0;
     }


     if((pid=fork())<0){

          printf("There have something wrong in the function of fork");
          return 0;

     }else if(pid==0){//child process
          printf("This is child process!\n");
          sendermsgp.mtype=1;
          char *sendmessage="serving for client";
          sprintf(sendermsgp.mtext,"%s %d","serving for client",getpid());


          msgsnd(msqid,&sendermsgp,strlen(sendermsgp.mtext)+1,0);
         // free(sendermsgp);
          printf("child send message:%s\n",sendermsgp.mtext);
          

         
          printf("child process get sleep for watting the message gived by parent\n");
          sleep(3);
          sendermsgp.mtype=1;
          msgsnd(msqid,&sendermsgp,strlen(sendermsgp.mtext)+1,0);
          sprintf(sendermsgp.mtext,"%d",getpid());
          printf("this is child second time send to parent context:%s\n",sendermsgp.mtext);
           


          int number;           
          number=msgrcv(msqid,&recevermsgp,1024,0,0);
          printf("-----child received message:%s\n",recevermsgp.mtext);
          printf("end of child process\n");
          
     }else{//parent process
          printf("This is parent process:%d\n",getpid());

          sleep(3);
          printf("--------------------------------\n");
          msgrcv(msqid,&recevermsgp,1024,0,0);
          printf("parent get child message::%s\n",recevermsgp.mtext);
         // free(recevermsgp);
          

          
          //parent give message to child
          recevermsgp.mtype=pid;
          sprintf(recevermsgp.mtext,"%d",getpid());
          printf("##################%s\n",recevermsgp.mtext);
          msgsnd(msqid,&recevermsgp,strlen(recevermsgp.mtext)+1,0);
          printf("end of parent process\n");
          sleep(2);
       
     } 
     return 0;
}

实验结果:
【操作系统】实验四:进程通信(二)【完整版实验报告】_第1张图片

你可能感兴趣的:(理论与基础)