• UNIX环境下的消息队列


      消息队列和共享内存一样,也是一种IPC对象。消息队列其实就是消息的链表,每一则消息都是用户自己的结构体。服务端这边创建消息队列,客户端这边打开消息队列,两个进程就可以进行通信。创建和打开消息队列使用函数msgget,发送消息到消息队列使用函数msgsnd,从消息队列中取出消息使用函数msgrcv,通信完毕后删除消息队列使用函数msgctl。这四个函数就是消息队列通信编程主要用到的函数,man命令就可以看到他们的详细信息。

      前面说到消息是用户自己构造的结构体,其实这个结构体也是有讲究的,这是linux给出的原型

    struct msgbuf {
                   long mtype;       /* message type, must be > 0 */
                   char mtext[1];    /* message data */
               };

      第一个是整形数字,标识消息的类型,可由用户自己定义。第二个就是消息的内容。其他部分可由用户自己添加。下面直接贴代码吧,感觉代码比文字更直观。我这里只是扫盲式的学了一下,接收消息的时候比较简单粗暴,直接接受了当前队列的第一则消息,没有设置其他的标志。

    /*send.c*/

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

    
    

    struct msgt
    {
    /*消息类型*/
    int msgtype;
    char student_num[20];
    char name[20];
    };

    
    

    int main(int argc, char const *argv[])
    {
    int msgid;
    int running = 1;
    int msg_type;
    char number[20];
    char str[20];

    
    

    struct msgt* msgs = (struct msgt*) malloc( sizeof(struct msgt));

    
    

    /*构造键值*/
    key_t key = ftok(".", 4);

    
    

    /*创建消息队列*/
    msgid = msgget(key, IPC_CREAT|0666);
    printf("msgid is %d ", msgid);

    
    

    /*循环*/
    while(running)
    {
    printf("please input message type, 0 for quit ");
    /*从键盘中读入消息类型和数据*/
    scanf("%d", &msg_type);
    if(msg_type == 0)
    {
    running = 0;
    msgs->msgtype = msg_type;
    msgsnd(msgid, (const void *)msgs, sizeof(struct msgt), 0);
    break;
    }
    printf("please input your student number ");
    scanf("%s", &number);

    
    


    printf("please input your name ");
    scanf("%s", str);
    /*将消息发送到消息队列*/
    msgs->msgtype = msg_type;
    strcpy(msgs->student_num, number);
    strcpy(msgs->name, str);
    msgsnd(msgid, (const void *)msgs, sizeof(struct msgt), 0);

    
    

    }

    
    

    /*删除消息队列*/
    msgctl(msgid, IPC_RMID, 0);

    
    

    free((void *) msgs);

    
    

    return 0;
    }

     
    /*recieve.c*/

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

    
    

    struct msgt
    {
    /*消息类型*/
    int msgtype;
    char student_num[20];
    char name[20];
    };

    
    

    int main(int argc, char const *argv[])
    {

    int i;
    int size;
    int msgid;

    struct msgt* msgs = (struct msgt*) malloc( sizeof(struct msgt));

    
    

    /*构造键值*/
    key_t key = ftok(".", 4);

    
    

    /*打开消息队列*/
    msgid = msgget(key, IPC_EXCL);

    
    

    printf("msgid is %d ", msgid);

    
    

    while(1)
    {
    size = msgrcv(msgid, msgs, sizeof(struct msgt), 0, 0);
    if(size == -1)
    return;
    printf("your student number is %s your name is %s size is %d ", msgs->student_num, msgs->name, size);


    }
    free((void *) msgs);

    
    

    return 0;
    }

     

      这里说点写这个程序出现的问题,一开始定义消息结构体的时候我是这么干的

    struct msgt* msgs;

      正常运行发送和接收都还好,但是当send输入0退出程序时就出现段错误了,最后用core dump定位才发现定义结构体指针没有初始化,就这破问题调了好久,血淋淋的教训。以后再敲代码的时候一定要记住,结构体指针需要malloc初始化!!!嗯!

      如果有错误或者疑问,欢迎指出!

  • 相关阅读:
    贝云cms内容管理系统(thinkphp5.0开源cms管理系统)
    NGINX.conf配置文件支持pathinfo
    阿里云视频直播PHPSDK接入教程
    如何在Nginx下配置PHP程序环境
    tomcat 内存参数优化示例
    12组免费的CSS3按钮强力推荐 狼人:
    9款jQuery插件为你的网站增加亮点 狼人:
    TUP第11期:腾讯、豆瓣精英实例诠释互联网研发之道 狼人:
    【TUP第11期】腾讯黄朝兴:浅谈客户端架构 狼人:
    Linus Torvalds:回顾Linux20年 狼人:
  • 原文地址:https://www.cnblogs.com/51qianrushi/p/4551382.html
Copyright © 2020-2023  润新知