Linux程序设计笔记--IPC操作--message queue

来源:互联网 发布:2017人工智能计算大会 编辑:程序博客网 时间:2024/06/05 12:44

3,消息队列

进程间传递数据,如果数据量比较小的话,使用消息队列。消息结构有两个限制:消息大小不能操作系统规定最大值。必须以一个long整数开始。


消息队列相关函数。

int msgget(key_tkey,int msgflg);

key_t key键值可以随意选择,特殊键值IPC_PRIVATE,创建只能有本进程使用的消息。

msgflg访问权限。类似信号量和共享内存。


int msgsnd(intmsgid,const void *msg_ptr,size_t msg_size,int msgflg);

msgid消息队列标示符。

msg_ptr消息指针,指向将要发送的消息,这个消息必须以一个长整数开始。

msg_size消息大小,不包括消息开头的长整数。

msgflg控制着消息队列满或者到达系统上限时采取的动作。如果设置为IPC_NOWAIT,消息队列满后,此调用立马返回-1,不阻塞。

如果IPC_NOWAIT标识被清除,次调用将被挂起,直到队列腾出空间后,操作完后返回。

int msgrcv(intmsgid,void *msg_ptr,size_t msg_sz,long int msg_type,int msgflg);

msgid消息队列标示符。

msg_ptr消息接受缓冲区,该结构和msgsnd中定义的结构相同。

msg_szmsg_ptr所指向的消息的长度,不包括开头长整数。

msg_type消息类型,如果想按照发送顺序接受消息,该值赋值为0。如果想检索某一特定的消息,只需要设定为特定的类型即可。

msgflg控制着消息队列满或者到达系统上限时采取的动作。如果设置为IPC_NOWAIT,消息队列为空时,此调用立马返回-1,不阻塞。

如果IPC_NOWAIT标识被清除,此调用将被挂起,直到队列中有消息位置,操作完后返回。

int msgctl(intmsgid,int command,struct msgid_ds *buf);

struct msgid_ds

{

    uid_t msg_perm.uid;

   uid_t msg_perm.gid;

   mode_tmsg_perm.mode;

};

IPC_STAT获取当前共享内存的状态信息,放到msgid_ds结构中。

IPC_SETmsgid_ds结构中的数据设置为共享内存的当前关联值。

IPC_RMID 删除消息队列。


message_queue2


#include <stdlib.h>

#include <stdio.h>

#include <string.h>

#include <errno.h>

#include <unistd.h>


#include <sys/msg.h>


#define MAX_TEXT 512


struct my_msg_st {

   long intmy_msg_type;

   charsome_text[MAX_TEXT];

};


int main()

{

   int running = 1;

   struct my_msg_stsome_data;

   int msgid;

   charbuffer[BUFSIZ];


   msgid =msgget((key_t)1234, 0666 | IPC_CREAT);


   if (msgid == -1){

      fprintf(stderr, "msgget failed with error: %d\n", errno);

      exit(EXIT_FAILURE);

   }


   while(running) {

      printf("Enter some text: ");

      fgets(buffer, BUFSIZ, stdin);

      some_data.my_msg_type = 1;

      strcpy(some_data.some_text, buffer);


      if(msgsnd(msgid, (void *)&some_data, MAX_TEXT, 0) == -1) {

         fprintf(stderr, "msgsnd failed\n");

         exit(EXIT_FAILURE);

      }

      if(strncmp(buffer, "end", 3) == 0) {

         running= 0;

      }

   }


   exit(EXIT_SUCCESS);

}


message queue1


#include <stdlib.h>

#include <stdio.h>

#include <string.h>

#include <errno.h>

#include <unistd.h>


#include <sys/msg.h>


struct my_msg_st {

   long intmy_msg_type;

   charsome_text[BUFSIZ];

};


int main()

{

   int running = 1;

   int msgid;

   struct my_msg_stsome_data;

   long intmsg_to_receive = 0;


   msgid =msgget((key_t)1234, 0666 | IPC_CREAT);


   if (msgid == -1){

      fprintf(stderr, "msgget failed with error: %d\n", errno);

      exit(EXIT_FAILURE);

   }   


   while(running) {

      if(msgrcv(msgid, (void *)&some_data, BUFSIZ, msg_to_receive, 0) == -1) {

         fprintf(stderr, "msgrcv failed with error: %d\n", errno);

         exit(EXIT_FAILURE);

      }

      printf("Youwrote: %s", some_data.some_text);

      if(strncmp(some_data.some_text, "end", 3) == 0) {

         running= 0;

      }

   }


   if(msgctl(msgid, IPC_RMID, 0) == -1) {

      fprintf(stderr, "msgctl(IPC_RMID) failed\n");

      exit(EXIT_FAILURE);

   }

   exit(EXIT_SUCCESS);

}



原创粉丝点击