zoukankan      html  css  js  c++  java
  • linux消息队列编程实例

    转自:linux 消息队列实例 

    前言:

       消息队列就是一个消息的链表。可以把消息看作一个记录,具有特定的格式以及特定的优先级。对消息队列有写权限的进程可以向其中按照一定的规则添加新消息;对消息队列有读权限的进程则可以从消息队列中读走消息

    函数:


    1.创建新消息队列或取得已存在消息队列

    原型:int msgget(key_t key, int msgflg);

    参数:

         key:可以认为是一个端口号,也可以由函数ftok生成。

         msgflg:IPC_CREAT值,若没有该队列,则创建一个并返回新标识符;若已存在,则返回原标识符。

                    IPC_EXCL值,若没有该队列,则返回-1;若已存在,则返回0。

    2.向队列读/写消息

    原型:

    msgrcv从队列中取用消息:ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);

    msgsnd将数据放到消息队列中:int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);

    参数:

         msqid:消息队列的标识码

         msgp:指向消息缓冲区的指针,此位置用来暂时存储发送和接收的消息,是一个用户可定义的通用结构,形态如下: 

    struct msgstru{
        long mtype; //大于0
        char mtext[512];
    };

         msgsz:消息的大小。

         msgtyp:从消息队列内读取的消息形态。如果值为零,则表示消息队列中的所有消息都会被读取。

      msgflg:用来指明核心程序在队列没有数据的情况下所应采取的行动。如果msgflg和常数IPC_NOWAIT合用,则在msgsnd()执行时若是消息队列已满,则msgsnd()将不会阻塞,而会立即返回-1,如果执行的是msgrcv(),则在消息队列呈空时,不做等待马上返回-1,并设定错误码为ENOMSG。当msgflg为0时,msgsnd()及msgrcv()在队列呈满或呈空的情形时,采取阻塞等待的处理模式。

    3.设置消息队列属性

    原型:int msgctl ( int msgqid, int cmd, struct msqid_ds *buf );

    参数:msgctl 系统调用对 msgqid 标识的消息队列执行 cmd 操作,系统定义了 3 种 cmd 操作: IPC_STAT , IPC_SET , IPC_RMID
          IPC_STAT : 该命令用来获取消息队列对应的 msqid_ds 数据结构,并将其保存到 buf 指定的地址空间。
          IPC_SET : 该命令用来设置消息队列的属性,要设置的属性存储在buf中。     

          IPC_RMID : 从内核中删除 msqid 标识的消息队列。

    实例:

    消息发送端:send.c

     1 /*send.c*/  
     2 #include <stdio.h>   
     3 #include <sys/types.h>   
     4 #include <sys/ipc.h>   
     5 #include <sys/msg.h>   
     6 #include <errno.h>   
     7 
     8 #define MSGKEY 1024   
     9   
    10 struct msgstru  
    11 {  
    12    long msgtype;  
    13    char msgtext[2048];   
    14 };  
    15   
    16 main()  
    17 {  
    18   struct msgstru msgs;  
    19   int msg_type;  
    20   char str[256];  
    21   int ret_value;  
    22   int msqid;  
    23   
    24   msqid=msgget(MSGKEY,IPC_EXCL);  /*检查消息队列是否存在*/  
    25   if(msqid < 0){  
    26     msqid = msgget(MSGKEY,IPC_CREAT|0666);/*创建消息队列*/  
    27     if(msqid <0){  
    28     printf("failed to create msq | errno=%d [%s]
    ",errno,strerror(errno));  
    29     exit(-1);  
    30     }  
    31   }   
    32    
    33   while (1){  
    34     printf("input message type(end:0):");  
    35     scanf("%d",&msg_type);  
    36     if (msg_type == 0)  
    37        break;  
    38     printf("input message to be sent:");  
    39     scanf ("%s",str);  
    40     msgs.msgtype = msg_type;  
    41     strcpy(msgs.msgtext, str);  
    42     /* 发送消息队列 */  
    43     ret_value = msgsnd(msqid,&msgs,sizeof(struct msgstru),IPC_NOWAIT);  
    44     if ( ret_value < 0 ) {  
    45        printf("msgsnd() write msg failed,errno=%d[%s]
    ",errno,strerror(errno));  
    46        exit(-1);  
    47     }  
    48   }  
    49   msgctl(msqid,IPC_RMID,0); //删除消息队列   
    50 }  

    消息接收端 receive.c

     1 /*receive.c */  
     2 #include <stdio.h>   
     3 #include <sys/types.h>   
     4 #include <sys/ipc.h>   
     5 #include <sys/msg.h>   
     6 #include <errno.h>   
     7   
     8 #define MSGKEY 1024   
     9   
    10 struct msgstru  
    11 {  
    12    long msgtype;  
    13    char msgtext[2048];  
    14 };  
    15   
    16 /*子进程,监听消息队列*/  
    17 void childproc(){  
    18   struct msgstru msgs;  
    19   int msgid,ret_value;  
    20   char str[512];  
    21     
    22   while(1){  
    23      msgid = msgget(MSGKEY,IPC_EXCL );/*检查消息队列是否存在 */  
    24      if(msgid < 0){  
    25         printf("msq not existed! errno=%d [%s]
    ",errno,strerror(errno));  
    26         sleep(2);  
    27         continue;  
    28      }  
    29      /*接收消息队列*/  
    30      ret_value = msgrcv(msgid,&msgs,sizeof(struct msgstru),0,0);  
    31      printf("text=[%s] pid=[%d]
    ",msgs.msgtext,getpid());  
    32   }  
    33   return;  
    34 }  
    35   
    36 void main()  
    37 {  
    38   int i,cpid;  
    39   
    40   /* create 5 child process */  
    41   for (i=0;i<5;i++){  
    42      cpid = fork();  
    43      if (cpid < 0)  
    44         printf("fork failed
    ");  
    45      else if (cpid ==0) /*child process*/  
    46         childproc();  
    47   }  
    48 }  
    49     
  • 相关阅读:
    Java学习二十九天
    Java学习二十八天
    47. Permutations II 全排列可重复版本
    46. Permutations 全排列,无重复
    subset ii 子集 有重复元素
    339. Nested List Weight Sum 339.嵌套列表权重总和
    251. Flatten 2D Vector 平铺二维矩阵
    217. Contains Duplicate数组重复元素
    209. Minimum Size Subarray Sum 结果大于等于目标的最小长度数组
    438. Find All Anagrams in a String 查找字符串中的所有Anagrams
  • 原文地址:https://www.cnblogs.com/lpshou/p/3145651.html
Copyright © 2011-2022 走看看