码迷,mamicode.com
首页 > 系统相关 > 详细

进程间通信 :消息队列的实现

时间:2016-04-12 07:48:11      阅读:218      评论:0      收藏:0      [点我收藏+]

标签:消息队列

一.消息队列

    消息队列是一个进程向另一个进程发送一个数据块的方法,所以消息队列是基于消息的,而管道则是基于字节流的。消息队列提供的是进程间的双向通信。

消息队列中的几个原型函数:

   1.获取消息信息:int msgget(key_t key,int msgflag);key 是用ftok()函数创建的

   2.接收消息:ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);

   3.发送消息:int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);

   4.销毁消息信息:int msfctl(int msgid)

查看key值命令:ipcs -q

删除key值命令:ipcs -q key值                    

//comm.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<unistd.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#define _PATH_ "."  //路径
#define _PROJ_ID_ 0x7777  
#define _BLOCK_SIZE_ 1024
#define _CLIENT_TYPE_ 1
#define _SERVER_TYPE_ 2
struct msgBuf  //定义一个消息结构体
{
  long mtype; //消息类型
  char mtext[_BLOCK_SIZE_];
 };

static int creat_msg_queue(); 
int get_msg_queue();
int send_msg_queue(int msg_id,const char*info,long type);
int recv_msg_queue(int msg_id,char info[],long type);
int destroy_msg_queue(int msg_id);

//comm.c

#include"comm.h"

int get_msg_queue()
{
  return creat_msg_queue();
 }

static int creat_msg_queue()
{
  key_t key=ftok(_PATH_,_PROJ_ID_);
  if(key<0)
   {
     perror("ftok");
     return -1;
    }
  int msg_id=msgget(key,IPC_CREAT);
  if(msg_id<0)
  {
    perror("msgget");
    return -1;
   }

   return msg_id;
}


int send_msg_queue(int msg_id,const char*info,long type)//将要发送的消息存入mtext中
{
   struct msgBuf msg;
   msg.mtype=type;
   memset(msg.mtext,‘\0‘,sizeof(msg.mtext));
   strcpy(msg.mtext,info);
   if(msgsnd(msg_id,&msg,sizeof(msg.mtext),0)<0)
   {
     perror("msgsnd");
     return -1;

    }
    return 0;
}

int recv_msg_queue(int msg_id,char* info,long type)//将mtext中的消息拿出放入info中
{
  struct msgBuf msg;
  if(msgrcv(msg_id,&msg,sizeof(msg.mtext),type,0)<0)
  {  
     perror("msgrcv");
     return -1;
   }
   strcpy(info,msg.mtext);
   return 0;
}

int destroy_msg_queue(int msg_id)
{
  if(msgctl(msg_id,IPC_RMID,NULL)<0)
  {
    perror("msgctl");
    return -1;
  }
  return 0;

}
                                                                                         //server.c  先发送后接收
                                                                                         
#include"comm.h"

int main()
{
  int msgid=get_msg_queue();
  if(msgid<0)
  {
    exit(1);
   }
   char info[_BLOCK_SIZE_];

   while(1)
   {
     memset(info,‘\0‘,sizeof(info));
     printf("please input:");
     fflush(stdout);
     gets(info);
     if(send_msg_queue(msgid,info,_SERVER_TYPE_)<0)
      {
        printf("send  information failed\n");
        exit(1);
       }
      if(recv_msg_queue(msgid,info,_CLIENT_TYPE_)<0)
      {
        printf("recieve information failed\n");
        exit(1);
     }
     printf("client:%s\n",info);
}
  destroy(msgid);
  return 0;
}


//client.c 先接收后发送
 #include"comm.h"
 int main()
{
   int msgid=get_msg_queue();
    if(msgid<0)
     {
      exit(1);
      }
     char info[_BLOCK_SIZE_];
     memset(info,‘\0‘,sizeof(info));
     printf("when input stop endding...\n");
     while(1)
     {
        if(recv_msg_queue(msgid,info,_SERVER_TYPE_)<0)
          {
            printf("recieve information failed\n");
            exit(1);
           }
       else
         {
   
           if(strcmp("stop",info)==0)
           {
             return 0;
            }
          printf("server :%s\n",info);
         }

      printf("please input:");
      fflush(stdout);
      gets(info);
      if(send_msg_queue(msgid,info,_CLIENT_TYPE_)<0)
       {
         printf("send information failed\n");
         exit(1);
        }
    }
  destroy(msgid);
  return 0;

}

运行结果:

技术分享






本文出自 “输出菱形图案” 博客,请务必保留此出处http://10541571.blog.51cto.com/10531571/1762739

进程间通信 :消息队列的实现

标签:消息队列

原文地址:http://10541571.blog.51cto.com/10531571/1762739

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!