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|, |[email protected]|
 *        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\":\n\t- stores at most %ld messages\n\t- \
        large at most %ld bytes each\n\t- currently holds %ld messages\n",
        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\n", 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|, |[email protected]|
 *        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\":\n\t- stores at most %ld messages\n\t- \
        large at most %ld bytes each\n\t- currently holds %ld messages\n",
        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\n", 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
时间: 2024-10-08 20:27:12

Linux 进程间通信(posix消息队列 简单)实例的相关文章

LInux进程间通信之消息队列编程实例

本文主要通过消息队列的编程实例来加深对消息队列的理解. 一.消息队列之创建 创建一个消息队列,需要用到一个函数: #include<sys/types.h> #include<sys/ipc.h> #include<sys/msg.h> int msgget(key_t key,int msgflg); key:需要调用ftok函数来获取. msgflg:IPC_CREAT,不存在则创建,存在则返回已有的qid. IPC_CREAT|IPC_EXCL,不存在则创建,存在

Linux进程间通信(二) - 消息队列

消息队列 消息队列是Linux IPC中很常用的一种通信方式,它通常用来在不同进程间发送特定格式的消息数据. 消息队列和之前讨论过的管道和FIFO有很大的区别,主要有以下两点(管道请查阅我的另一篇文章:http://www.cnblogs.com/linuxbug/p/4863724.html): Ø  一个进程向消息队列写入消息之前,并不需要某个进程在该队列上等待该消息的到达,而管道和FIFO是相反的,进程向其中写消息时,管道和FIFO必须已经打开来读,否则写进程就会阻塞(默认情况下). Ø 

练习--LINUX进程间通信之消息队列MSG

https://www.ibm.com/developerworks/cn/linux/l-ipc/part3/ 继续坚持,或许不能深刻理解,但至少要保证有印象. ~~~~~~~~~~~~~~ 消息队列(也叫做报文队列)能够克服早期unix通信机制的一些缺点.作为早期unix通信机制之一的信号能够传送的信息量有限,后来虽然POSIX 1003.1b在信号的实时性方面作了拓广,使得信号在传递信息量方面有了相当程度的改进,但是信号这种通信方式更像"即时"的通信方式,它要求接受信号的进程在某

[转]Linux进程间通信——使用消息队列

点击此处阅读原文 另收藏ljianhui的专栏初学Linux 下面来说说如何用不用消息队列来进行进程间的通信,消息队列与命名管道有很多相似之处.有关命名管道的更多内容可以参阅我的另一篇文章:Linux进程间通信--使用命名管道 一.什么是消息队列 消息队列提供了一种从一个进程向另一个进程发送一个数据块的方法.  每个数据块都被认为含有一个类型,接收进程可以独立地接收含有不同类型的数据结构.我们可以通过发送消息来避免命名管道的同步和阻塞问题.但是消息队列与命名管道一样,每个数据块都有一个最大长度的

Linux进程间通信——使用消息队列

下面来说说如何用不用消息队列来进行进程间的通信,消息队列与命名管道有很多相似之处.有关命名管道的更多内容可以参阅我的另一篇文章:Linux进程间通信--使用命名管道 一.什么是消息队列 消息队列提供了一种从一个进程向另一个进程发送一个数据块的方法.  每个数据块都被认为含有一个类型,接收进程可以独立地接收含有不同类型的数据结构.我们可以通过发送消息来避免命名管道的同步和阻塞问题.但是消息队列与命名管道一样,每个数据块都有一个最大长度的限制. Linux用宏MSGMAX和MSGMNB来限制一条消息

linux进程间通信之消息队列

我们已经知道进程通信的方式是有多种的,在上一篇博客中讲述了通过管道实现简单的进程间通信,那么接下来我们看看与之类似的另一种方式,通过消息队列来实现进程间通信. 什么是消息队列 消息队列提供了一种由一个进程向另一个进程发送块数据的方法.另外,每一个数据块被看作有一个类型,而接收进程可以独立接收具有不同类型的数据块.消息队列的好处在于我们几乎可以完全避免同步问题,并且可以通过发送消息屏蔽有名管道的问题.更好的是,我们可以使用某些紧急方式发送消息.坏处在于,与管道类似,在每一个数据块上有一个最大尺寸限

Linux进程间通信(消息队列/信号量+共享内存)

写在前面 不得不说,Deadline果真是第一生产力.不过做出来的东西真的是不堪入目,于是又花了一早上重写代码. 实验内容 进程通信的邮箱方式由操作系统提供形如 send()和 receive()的系统调用来支持,本实验要求学生首先查找资料了解所选用操作系统平台上用于进程通信的系统调用具体形式,然后使用该系统调用编写程序进行进程间的通信,要求程序运行结果可以直观地体现在界面上.在此基础上查找所选用操作系统平台上支持信号量机制的系统调用具体形式,运用生产者与消费者模型设计实现一个简单的信箱,该信箱

Linux进程间通信:消息队列

一.什么是消息队列 消息队列提供了一种从一个进程向另一个进程发送一个数据块的方法. 每个数据块都被认 为是有一个类型,接收者进程接收的数据块可以有不同的类型值.我们可以通过发送消息 来避免命名管道的同步和阻塞问题.消息队列与管道不同的是,消息队列是基于消息的, 而管道是基于字节流的,且消息队列的读取不一定是先入先出.消息队列与命名管道有一 样的不足,就是每个消息的最大长度是有上限的(MSGMAX),每个消息队列的总的字节 数是有上限的(MSGMNB),系统上消息队列的总数也有一个上限(MSGMN

Linux环境编程之IPC进程间通信(五):Posix消息队列1

对于管道和FIFO来说,必须应该先有读取者存在,否则先有写入者是没有意义的.而消息队列则不同,它是一个消息链表,有足够写权限的线程可往别的队列中放置消息,有足够读权限的线程可从队列中取走消息.每个消息都是一个记录,它由发送者赋予一个优先级.在某个进程往一个队列写入消息之前,并不需要另外某个进程在该队列上等待消息的到达.消息队列是随内核的持续性,一个进程可以往某个队列写入一些消息,然后终止,再让另外一个进程在以后的某个时刻读出这些消息.这跟管道和FIFO不一样,当一个管道或FIFO的最后一次关闭时