无法设置 POSIX 消息队列属性

sev*_*ine 5 c linux queue posix

我的环境:

  • CentOS 6.5(64位内核)
  • 海湾合作委员会 4.4.7 20120313

我正在尝试设置 POSIX 消息队列的属性,但代码不会更改该属性。我只获得默认属性值。

你能指出我的代码有什么问题吗?

我以用户(而不是 root)身份执行 a.out。

#include <stdio.h>
#include <mqueue.h> // for message queue
#include <sys/stat.h>
#include <stdlib.h> // for EXIT_FAILURE
#include <string.h>

/*
gcc [file] -lrt
*/

static void showAttr(mqd_t mqd)
{
    struct mq_attr attr;

    mq_getattr(mqd, &attr);

    printf("maxmsg = %d\n", attr.mq_maxmsg);
    printf("msgsize = %d\n", attr.mq_msgsize);
    printf("curmsgs = %d\n", attr.mq_curmsgs);

}

int main()
{
    mqd_t mqd;
    int flags;
    int ret;
    struct mq_attr attr;

    flags = O_RDWR | O_CREAT;

    attr.mq_flags = 0; // or O_NONBLOCK
    attr.mq_maxmsg = 60;
    attr.mq_msgsize = 120;
    attr.mq_curmsgs = 0;

    // POSIX IPC name should start with "/"
    mqd = mq_open("/mq", flags,
//      (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH),
        0644,
        &attr );

    if (mqd < 0) {
        printf("open failed\n");
        exit(EXIT_FAILURE);
    }
    printf("open ok\n");

    sleep(1);

    showAttr(mqd);

    ret = mq_close(mqd);
    if (ret != 0) {
        printf("open failed\n");
        exit(EXIT_FAILURE);     
    }
    printf("close ok\n");

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我发现以下代码有效。但是,当我尝试设置 attr.mq_maxmsg (=60) 时,mq_open 失败。

#include <stdio.h>
#include <mqueue.h> // for message queue
#include <sys/stat.h>
#include <stdlib.h> // for EXIT_FAILURE
#include <string.h>
#include <errno.h>

/*
gcc [file] -lrt
*/

static void showAttr(mqd_t mqd)
{
    struct mq_attr attr;

    mq_getattr(mqd, &attr);

    printf("maxmsg = %d\n", attr.mq_maxmsg);
    printf("msgsize = %d\n", attr.mq_msgsize);
    printf("curmsgs = %d\n", attr.mq_curmsgs);

}

int main()
{
    mqd_t mqd;
    int flags;
    int ret;
    struct mq_attr attr;

    flags = O_RDWR | O_CREAT;

    // POSIX IPC name should start with "/"

    // 1. once open without attribute setting
    mqd = mq_open("/mq", flags,
        (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) );
    mq_getattr(mqd, &attr);
    mq_unlink("/mq");
    mq_close(mqd);

    // 2. set values of attribute
    // attr.mq_maxmsg = 10;
    attr.mq_msgsize = 120;

    // 3. allocate attribute
    mqd = mq_open("/mq", flags,
        (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH),
    //   0644,
        &attr );

    if (mqd < 0) {
        printf("open failed %d\n", mqd);
        exit(EXIT_FAILURE);
    }
    printf("open ok\n");

    sleep(1);

    showAttr(mqd);


    ret = mq_close(mqd);
    if (ret != 0) {
        printf("open failed\n");
        exit(EXIT_FAILURE);     
    }
    printf("close ok\n");

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

pil*_*row 2

mq_open()返回一个已经存在的队列,其属性是在创建时设置的。因此,O_CREAT 标志不起作用,并且您指定的属性也会被忽略。

在打开之前调用mq_unlink(),也许还设置 O_EXCL,并查看差异。