Chinaunix首页 | 论坛 | 博客
  • 博客访问: 265256
  • 博文数量: 74
  • 博客积分: 1470
  • 博客等级: 上尉
  • 技术积分: 793
  • 用 户 组: 普通用户
  • 注册时间: 2008-11-25 21:01
文章分类

全部博文(74)

文章存档

2011年(1)

2010年(32)

2009年(32)

2008年(9)

我的朋友

分类: C/C++

2010-04-09 15:49:22

在上篇进程内存查看工具之共享内存的最后提到了共享内存的几个缺点,然后提出了可以改用消息队列来完成进程特定内存的查看.
下面就用消息队列的方式来实现上篇开始处提到的需求:
master.c首先接收一个发送请求,然后发送用户输入的数据给接收方tool

/*
 * =====================================================================================
 *
 * Filename: master.c
 *
 * Description:
 *
 * Version: 1.0
 * Created: 04/09/2010 11:17:16 AM
 * Revision: none
 * Compiler: gcc
 *
 * Author: LeiuX (xulei), xulei@pact518.hit.edu.cn
 * Company: HIT
 *
 * =====================================================================================
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

#define BUF_SIZE 32
#define MY_PROC_SND_TYPE 2
#define MY_PROC_RCV_TYPE 3

#define MY_PROC_ID 4
#define MY_PROC_PATH "/tmp/msgqueue"

struct mymsgst{
  long type;
  char data[BUF_SIZE];
};

int main()
{
  key_t my_msg_kt;
  int msgid;
  struct mymsgst my_msg;
  char buffer[BUF_SIZE] = {0};

  /* 获取消息队列的 ID */
  my_msg_kt = ftok(MY_PROC_PATH, MY_PROC_ID);
  msgid = msgget(my_msg_kt, 0666|IPC_CREAT);
  if (msgid < 0) {
    printf("msgget failed with error: %s ,ERRNO=0x%x\n",strerror(errno),errno);
    exit(EXIT_FAILURE);
  }

  while(1)
  {
    //接收发送请求

    if(msgrcv(msgid, (void*)&my_msg, BUF_SIZE, MY_PROC_RCV_TYPE,0) == -1) {
      printf("msgrcv failed with error: %s ,ERRNO=0x%x\n",strerror(errno),errno);
      exit(EXIT_FAILURE);
    }

    if(strncmp(my_msg.data, "send start", 10) == 0)
    {
      printf("Please input data: ");
      fgets(buffer, BUF_SIZE, stdin);
      strncpy(my_msg.data, buffer, sizeof(my_msg.data));
      my_msg.data[BUF_SIZE-1] = '\0';

      /* 设置消息类型 */
      my_msg.type = MY_PROC_SND_TYPE;
      //发送数据

      if(msgsnd(msgid, (void*)&my_msg, BUF_SIZE, 0) == -1) {
        printf("msgsnd failed with error: %s ,ERRNO=0x%x\n",strerror(errno),errno);
        exit(EXIT_FAILURE);
      }
    }
  }
  exit(EXIT_SUCCESS);
}



tool.c首先发送一个接收请求,然后接收master发送过来的数据

/*
 * =====================================================================================
 *
 * Filename: tool.c
 *
 * Description:
 *
 * Version: 1.0
 * Created: 04/09/2010 11:16:29 AM
 * Revision: none
 * Compiler: gcc
 *
 * Author: LeiuX (xulei), xulei@pact518.hit.edu.cn
 * Company: HIT
 *
 * =====================================================================================
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

#define BUF_SIZE 32
#define MY_PROC_RCV_TYPE 2
#define MY_PROC_SND_TYPE 3

#define MY_PROC_ID 4
#define MY_PROC_PATH "/tmp/msgqueue"

struct mymsgst{
  long type;
  char data[BUF_SIZE];
};

int main()
{
  key_t my_msg_kt;
  int msgid;
  struct mymsgst my_msg;

  /* 获取消息队列的 ID */
  my_msg_kt = ftok(MY_PROC_PATH, MY_PROC_ID);
  msgid = msgget(my_msg_kt, 0666|IPC_CREAT);
  if (msgid < 0) {
    printf("msgget failed with error: %s ,ERRNO=0x%x\n",strerror(errno),errno);
    exit(EXIT_FAILURE);
  }

  //发送一个接收请求

  my_msg.type = MY_PROC_SND_TYPE;
  strncpy(my_msg.data, "send start", sizeof(my_msg.data));
  my_msg.data[BUF_SIZE-1] = '\0';
  if(msgsnd(msgid, (void*)&my_msg, BUF_SIZE, 0) == -1) {
    printf("msgsnd failed with error: %s ,ERRNO=0x%x\n",strerror(errno),errno);
    exit(EXIT_FAILURE);
  }

  //接收数据

  if(msgrcv(msgid, (void*)&my_msg, BUF_SIZE, MY_PROC_RCV_TYPE,0) == -1) {
    printf("msgrcv failed with error: %s ,ERRNO=0x%x\n",strerror(errno),errno);
    exit(EXIT_FAILURE);
  }
  printf("receive data: %s\n", my_msg.data);

/*
  if(msgctl(msgid, IPC_RMID, 0) == -1)
  {
    printf("msgctl failed with error: %s ,ERRNO=0x%x\n",strerror(errno),errno);
    exit(EXIT_FAILURE);
  }
*/

  exit(EXIT_SUCCESS);
}



运行结果:
~$ ./master
Please input data: abc
Please input data: def
Please input data: ddd

~$ ./tool
receive data: abc

~$ ./tool
receive data: def

~$ ./tool
receive data: ddd

在master运行其间,每运行一次tool,就会得到master传过来的不同的数据.

如果在master中需要msgsnd的数据是链表(或者其他动态数据),那么只需要给my_msg.data中放入相应的数据就行.相信读者可以自行完成.

reference:
进程通信之消息队列
http://blog.csdn.net/wzhwho/archive/2009/03/14/3990148.aspx


阅读(816) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~