Linux消息队列

POSIX消息队列

  • 使用man mq_overview命令查看POSIX消息队列编程手册
  • 头文件:include
  • 从消息队列中取出的是优先级最高且最先进入消息队列的消息

接收消息

#include 
#include 
#include 
#include 
#include 

#define MQ_NAME     "/my_mq"            //必须以斜杠/开头

struct msg_t {
    int32_t data;
};

int main()
{
    int len = sizeof(struct msg_t);

    struct mq_attr attr = {
            .mq_maxmsg = 10,    //消息队列大小
            .mq_msgsize = len,   //每个消息的大小
    };

    mqd_t  mq_fd = mq_open(MQ_NAME,O_CREAT | O_RDONLY, 0666, &attr);
    if (mq_fd == -1)
    {
        printf("mq_open failed: %s\n", strerror(errno));
        return 0;
    }
    struct msg_t msg;
    unsigned int prio;
    long ret = mq_receive(mq_fd, (char*)&msg,len, &prio);
    if (ret == -1)
    {
        printf("mq_send: %s\n", strerror(errno));
    }
    printf("mq received %ld bytes\n", ret);
    printf("%d %d\n",msg.data, prio);

    mq_close(mq_fd);
    mq_unlink(MQ_NAME);
    return 0;
}

监听消息

  • 消息通知触发的条件:消息队列为空,且有新消息到达时
  • 监听消息队列注册后只能触发1次,触发后需要重新注册
  • 同时只能有一个进程注册消息队列监听
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define MQ_NAME     "/my_mq"            //必须以斜杠/开头

struct msg_t {
    int32_t data;
};

static void handle_mq_msg(union sigval sv)
{

    mqd_t mq_fd = *((mqd_t*) sv.sival_ptr);
    struct msg_t msg;
    unsigned int prio;



    int ret = mq_receive(mq_fd, (char*)&msg,sizeof(struct msg_t), &prio);
    if (ret == -1)
    {
        printf("mq_receive failed: %s\n", strerror(errno));
    }
    printf("mq received %ld bytes\n", ret);
    printf("%d %d\n",msg.data, prio);

    ret = mq_notify(mq_fd, &sev);			//需要重新注册
    if (ret == -1)
    {
        printf("mq_notify failed: %s\n", strerror(errno));
    }
}

int main()
{
    int len = sizeof(struct msg_t);

    struct mq_attr attr = {
            .mq_maxmsg = 10,    //消息队列大小
            .mq_msgsize = len,   //每个消息的大小
    };

    mqd_t  mq_fd = mq_open(MQ_NAME,O_CREAT | O_RDONLY, 0666, &attr);
    if (mq_fd == -1)
    {
        printf("mq_open failed: %s\n", strerror(errno));
        return 0;
    }

    struct sigevent sev = {
            .sigev_notify = SIGEV_THREAD,
            .sigev_notify_function = handle_mq_msg,
            .sigev_notify_attributes = NULL,
            .sigev_value.sival_ptr = &mq_fd,
    };
    int ret = mq_notify(mq_fd, &sev);
    if (ret == -1)
    {
        printf("mq_notify failed: %s\n", strerror(errno));
    }

    pause();
    mq_close(mq_fd);
    mq_unlink(MQ_NAME);
    return 0;
}

发送消息

#include 
#include 
#include 
#include 
#include 

#define MQ_NAME     "/my_mq"            //必须与接收进程使用的消息队列同名

struct msg_t {
    int32_t data;
};

int main()
{

    mqd_t  mq_fd = mq_open(MQ_NAME,O_WRONLY);
    if (mq_fd == -1)
    {
        printf("mq_open failed: %s\n", strerror(errno));
        return 0;
    }
    struct msg_t msg = {8888};

    long ret = mq_send(mq_fd, (char*)&msg, sizeof(struct msg_t), 1);
    if (ret == -1)
    {
        printf("mq_send: %s\n", strerror(errno));
        return 0;
    }
    printf("mq send successfully\n");

    mq_close(mq_fd);
    return 0;
}

System V消息队列

你可能感兴趣的:(Linux,C语言,linux)