zoukankan      html  css  js  c++  java
  • Linux 进程间通信(posix消息队列 简单)实例

    Linux 进程间通信(posix消息队列 简单)实例
    
    详情见: http://www.linuxidc.com/Linux/2011-10/44828.htm
    
    编译:
    
    gcc -o consumer consumer.c -lrt
    
    gcc -o producer producer.c -lrt
    
    /*
    
     *
     *       Filename:  producer.c
     *
     *    Description:  生产者进程
     *
     *        Version:  1.0
     *        Created:  09/30/2011 04:52:23 PM
     *       Revision:  none
     *       Compiler:  gcc(g++)
     *
     *         Author:  |Zhenghe Zhang|, |zhenghe.zhang@gmail.com|
     *        Company:  |Shenzhen XXX Technology Co., Ltd.|
     *
     */
    
    #include <stdio.h>
    #include <mqueue.h>
    #include <sys/stat.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <time.h>
    #include <string.h>
    
    #define MAXSIZE     10   //定义buf大小
    #define BUFFER      8192 //定义Msg大小
    
    struct MsgType{
        int len;
        char buf[MAXSIZE];
        char x;
        short y;
    };
    可以用这种形式传递参数
    int main() 
    { 
        /*消息队列*/
        mqd_t msgq_id;
        struct MsgType msg;
    
        unsigned int prio = 1;
        unsigned int send_size = BUFFER;
    
        struct mq_attr msgq_attr;
        const char *file = "/posix";
    
        /*mq_open() for creating a new queue (using default attributes) */
        /*mq_open() 创建一个新的 POSIX 消息队列或打开一个存在的队列*/
        msgq_id = mq_open(file, O_RDWR | O_CREAT, S_IRWXU | S_IRWXG, NULL);
        if(msgq_id == (mqd_t)-1)
        {
            perror("mq_open");
            exit(1);
        }
    
        /* getting the attributes from the queue        --  mq_getattr() */
        if(mq_getattr(msgq_id, &msgq_attr) == -1)
        {
            perror("mq_getattr");
            exit(1);
        }
    
        printf("Queue "%s":
    	- stores at most %ld messages
    	- 
            large at most %ld bytes each
    	- currently holds %ld messages
    ", 
            file, msgq_attr.mq_maxmsg, msgq_attr.mq_msgsize, msgq_attr.mq_curmsgs);
       
        /*setting the attributes of the queue        --  mq_setattr() */
        /*mq_setattr() 设置消息队列的属性,设置时使用由 newattr 指针指向的 mq_attr 结构的信息。*/
        /*属性中只有标志 mq_flasgs 里的 O_NONBLOCK 标志可以更改,其它在 newattr 内的域都被忽略 */
        if(mq_setattr(msgq_id, &msgq_attr, NULL) == -1)
        {
            perror("mq_setattr");
            exit(1);
        }   
    
        int i = 0; 
        while(i < 10) 
        {
            msg.len = i;
            memset(msg.buf, 0, MAXSIZE);
            sprintf(msg.buf, "0x%x", i);
            msg.x = (char)(i + 'a');
            msg.y = (short)(i + 100);
    
            printf("msg.len = %d, msg.buf = %s, msg.x = %c, msg.y = %d
    ", msg.len, msg.buf, msg.x, msg.y);
    
            /*sending the message      --  mq_send() */
            /*mq_send() 把 msg_ptr 指向的消息加入由 mqdes 引用的消息队列里。*/
            /*参数 msg_len 指定消息 msg_ptr 的长度:这个长度必须小于或等于队列 mq_msgsize 属性的值。零长度的消息是允许。*/
            if(mq_send(msgq_id, (char*)&msg, sizeof(struct MsgType), prio) == -1)
            {
                perror("mq_send");
                exit(1);
            }
    
            i++;
            sleep(1);   
        }
    
        sleep(30); //等待消费者进程退出    这个意思就是先让生产者执行,但是消费者必须在30秒内执行,不然就会出问题
    
        /*closing the queue        -- mq_close() */
        /*mq_close() 关闭消息队列描述符 mqdes。如果调用进程在消息队列 mqdes 绑定了通知请求,*/
        /*那么这个请求被删除,此后其它进程就可以绑定通知请求到此消息队列。*/
        if(mq_close(msgq_id) == -1)
        {
            perror("mq_close");
            exit(1);
        }
    
        /*mq_unlink() 删除名为 name 的消息队列。消息队列名将被直接删除。*/
        /*消息队列本身在所有引用这个队列的描述符被关闭时销毁。*/
        if(mq_unlink(file) == -1)
        {
            perror("mq_unlink");
            exit(1);
        }
    
        return 0; 
    }
    
     
    
    
    /*
     *
     *       Filename:  consumer.c
     *
     *    Description:  消费者进程
     *
     *        Version:  1.0
     *        Created:  09/30/2011 04:52:23 PM
     *       Revision:  none
     *       Compiler:  gcc(g++)
     *
     *         Author:  |Zhenghe Zhang|, |zhenghe.zhang@gmail.com|
     *        Company:  |Shenzhen XXX Technology Co., Ltd.|
     *
     */
    
    #include <stdio.h>
    #include <mqueue.h>
    #include <sys/stat.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <time.h>
    #include <string.h>
    
    #define MAXSIZE     10   //定义buf大小
    #define BUFFER      8192 //定义Msg大小
    
    struct MsgType{
        int len;
        char buf[MAXSIZE];
        char x;
        short y;
    };
    
    int main() 
    { 
        /*消息队列*/
        mqd_t msgq_id;
        struct MsgType msg;
    
        unsigned int sender;
        struct mq_attr msgq_attr;
    
        unsigned int recv_size = BUFFER;
        const char *file = "/posix";
    
        /* mq_open() for opening an existing queue */
        msgq_id = mq_open(file, O_RDWR);
        if(msgq_id == (mqd_t)-1)
        {
            perror("mq_open");
            exit(1);
        }
    
        /* getting the attributes from the queue        --  mq_getattr() */
        if(mq_getattr(msgq_id, &msgq_attr) == -1)
        {
            perror("mq_getattr");
            exit(1);
        }
    
        printf("Queue "%s":
    	- stores at most %ld messages
    	- 
            large at most %ld bytes each
    	- currently holds %ld messages
    ", 
            file, msgq_attr.mq_maxmsg, msgq_attr.mq_msgsize, msgq_attr.mq_curmsgs);
    
        if(recv_size < msgq_attr.mq_msgsize)
            recv_size = msgq_attr.mq_msgsize;
    
        int i = 0;
        while(i < 10) //运行一个consumenr,为 10 ,同时运行两个consumer进程,为 5  
        {
            msg.len = -1;
            memset(msg.buf, 0, MAXSIZE);
            msg.x = ' ';
            msg.y = -1;
     
            /* getting a message */
    
            /*mq_receive() 从由描述符 mqdes 引用的队列时删除优先级最高的最老的消息,并把放置到 msg_ptr 的缓存区内。*/
            /*参数 msg_len 指定缓冲区 msg_ptr 的大小:它必须大于队列的 mq_msgsize 属性(参数 mq_getattr)。*/ 
            /*如果 prio 不是 NULL,那么它指向的内存用于返回收到消息相关的优先级。*/
            if (mq_receive(msgq_id, (char*)&msg, recv_size, &sender) == -1) 
            {
                perror("mq_receive");
                exit(1);
            }
    
            printf("msg.len = %d, msg.buf = %s, msg.x = %c, msg.y = %d
    ", msg.len, msg.buf, msg.x, msg.y);
    
            i++;
            sleep(2); 
        }
    
        if(mq_close(msgq_id) == -1)
        {
            perror("mq_close");
            exit(1);
        }
    
        return 0; 
    }
    http://www.linuxidc.com/Linux/2011-10/44829.htm
  • 相关阅读:
    博客园添加访问人数统计【转】
    Android环境下通过C框架层控制WIFI【转】
    用户态文件系统fuse学习【转】
    linux内核 RCU机制详解【转】
    使用diff制作补丁【学习笔记】
    OAuth2授权原理
    Code! MVC 5 App with Facebook, Twitter, LinkedIn and Google OAuth2 Sign-on (C#)
    lock关键字只不过是C#提供的语法糖
    关于OATUH中的AUTHRAZITON CODE和TOKEN的关系,实际上就是这么回事
    SQL Server 索引设计指南
  • 原文地址:https://www.cnblogs.com/leijiangtao/p/4084092.html
Copyright © 2011-2022 走看看