Chinaunix首页 | 论坛 | 博客
  • 博客访问: 702143
  • 博文数量: 152
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1793
  • 用 户 组: 普通用户
  • 注册时间: 2013-09-12 12:26
个人简介

相信自己,只有不想做的,没有做不到的。

文章分类

全部博文(152)

文章存档

2021年(1)

2015年(2)

2014年(74)

2013年(75)

分类: LINUX

2013-12-16 22:05:43

消息队列
特点:指定的类型读取/发送消息

A.消息结构体

typedef struct
{
 //消息类型必须在第一个字段
 long type;

 //正文部分
 /存放数据/
 char mtext[1024];
 /发送的PID/
 int pid;
 ....
}MSG;

//正文大小
#define MSG_LEN (sizeof(MSG) - sizeof(long))

B.发送消息
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
msgsnd(消息队列ID,消息存放的地址,消息正文大小,发送方式(IPC_NOWAIT:消息队列满,发送消息不阻塞,立即返回
; 0 : 阻塞的方式));

例如:发送消息类型是100,内容"hello word"
typedef struct
{
 long type;
 char mtext[1024];
}MSG;

MSG msg;

msg.type = 100;
strcpy(msg.mtext, "hello word");

msgsnd(msgid,&msg,MSG_LEN,0);

C.接受消息
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
msgrcv(消息队列ID,消息存放的地址,正文大小,消息的类型,读取的方式);

msgtyp: 0(总是读取消息队列第一个消息), > 0 (每次读取第一个指定的消息类型)
msgflg:0(要求读的消息类型不存在,阻塞),IPC_NOWAIT(如果没有要读的消息,不阻塞立即返回)

MSG msg;

msgrcv(msgid,&msg,MSG_LEN,100,0);

printf("*******************\n");
printf("TYPE : %d.\n",msg.type);
printf("MTEXT: %s.\n",msg.mtext);

实例如下:
msg_a,.c代码如下

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

#define MSG_TYPE_A 100
#define MSG_TYPE_B 200

typedef struct
{
 long type;
 char buf[1024];
}MSG;

#define MSG_LEN (sizeof(MSG) - sizeof(long))

int send_msg(int msg_id,int pid)
{
 MSG msg;
 
 while(1)
 {
  fgets(msg.buf,sizeof(msg.buf),stdin);
  msg.buf[strlen(msg.buf) - 1] = '\0';
  
  msg.type = MSG_TYPE_A;

  if(msgsnd(msg_id,&msg,MSG_LEN,0) < 0)
  {
   perror("Fail to msgsnd");
   exit(EXIT_FAILURE);
  }
  
  if(strncmp(msg.buf,"quit",4) == 0)
  {
   kill(pid,SIGUSR1);
   wait(NULL);
   break;
  }
 }

 return 0;
}

int recv_msg(int msg_id)
{
 MSG msg;

 while(1)
 {
  if(msgrcv(msg_id,&msg,MSG_LEN,MSG_TYPE_B,0) < 0)
  {
   perror("Fail to msgsnd");
   exit(EXIT_FAILURE);
  }

  printf("********************\n");
  printf("TYPE : %ld.\n",msg.type);
  printf("MTEXT: %s.\n",msg.buf);
  printf("********************\n");
  
  if(strncmp(msg.buf,"quit",4) == 0)
  {
   kill(getppid(),SIGUSR1);
   break;
  }
 }

 return 0;
}

int main(int argc, const char *argv[])
{
 int msg_id;
 key_t key;
 pid_t pid;


 if((key = ftok(argv[1],'k')) < 0)
 {
  perror("Fail to ftok");
  exit(EXIT_FAILURE);
 }
 
 if((msg_id = msgget(key,IPC_CREAT | 0666)) < 0)
 {
  perror("Fail to msgget");
  exit(EXIT_FAILURE);
 }

 if((pid = fork()) < 0)
 {
  perror("Fail to fork");
  exit(EXIT_FAILURE);
 }

 if(pid == 0)
 {
  recv_msg(msg_id);
 }

 if(pid > 0)
 {
  send_msg(msg_id,pid);
  //删除消息队列
  if(msgctl(msg_id,IPC_RMID,NULL) < 0)
  {
   perror("Fail to msgctl");
   exit(EXIT_FAILURE);
  }
 }
  
 exit(EXIT_SUCCESS);
}

msg_b.c代码如下

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

#define MSG_TYPE_A 200
#define MSG_TYPE_B 100

typedef struct
{
 long type;
 char buf[1024];
}MSG;

#define MSG_LEN (sizeof(MSG) - sizeof(long))

int send_msg(int msg_id,int pid)
{
 MSG msg;
 
 while(1)
 {
  fgets(msg.buf,sizeof(msg.buf),stdin);
  msg.buf[strlen(msg.buf) - 1] = '\0';
  
  msg.type = MSG_TYPE_A;

  if(msgsnd(msg_id,&msg,MSG_LEN,0) < 0)
  {
   perror("Fail to msgsnd");
   exit(EXIT_FAILURE);
  }
  
  if(strncmp(msg.buf,"quit",4) == 0)
  {
   kill(pid,SIGUSR1);
   wait(NULL);
   break;
  }
 }

 return 0;
}

int recv_msg(int msg_id)
{
 MSG msg;

 while(1)
 {
  if(msgrcv(msg_id,&msg,MSG_LEN,MSG_TYPE_B,0) < 0)
  {
   perror("Fail to msgsnd");
   exit(EXIT_FAILURE);
  }

  printf("********************\n");
  printf("TYPE : %ld.\n",msg.type);
  printf("MTEXT: %s.\n",msg.buf);
  printf("********************\n");
  
  if(strncmp(msg.buf,"quit",4) == 0)
  {
   kill(getppid(),SIGUSR1);
   break;
  }
 }

 return 0;
}

int main(int argc, const char *argv[])
{
 int msg_id;
 key_t key;
 pid_t pid;


 if((key = ftok(argv[1],'k')) < 0)
 {
  perror("Fail to ftok");
  exit(EXIT_FAILURE);
 }
 
 if((msg_id = msgget(key,IPC_CREAT | 0666)) < 0)
 {
  perror("Fail to msgget");
  exit(EXIT_FAILURE);
 }

 if((pid = fork()) < 0)
 {
  perror("Fail to fork");
  exit(EXIT_FAILURE);
 }

 if(pid == 0)
 {
  recv_msg(msg_id);
 }

 if(pid > 0)
 {
  send_msg(msg_id,pid);
  //删除消息队列
  if(msgctl(msg_id,IPC_RMID,NULL) < 0)
  {
   perror("Fail to msgctl");
   exit(EXIT_FAILURE);
  }
 }
  
 exit(EXIT_SUCCESS);
}


 

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