首页 文章

msgrcv没有等待具有errno 22(EINVAL)的特定消息类型的消息

提问于
浏览
0

我试图在标准C库中使用msgsnd和msgrcv系统调用,但没有达到预期/期望的性能 .

我的问题是,当我调用msgrcv时,它不会等待具有指定mtype(4)的消息 .

我首先发送一个mtype为1的消息 . 想法是另一个进程然后会收到此消息并发回一个mtype为4的确认消息 . 从documentation,我期望"if msgtyp is greater than zero, the first message of type msgtyp is received" .
我还希望它等到消息类型为msgtyp的消息在队列中 . 从文档:

  • 如果msgflg参数中未设置IPC_NOWAIT标志,则调用线程将暂停处理,直到出现以下情况之一:

  • 将所需类型的消息发送到消息队列 .

  • 消息队列标识符msqid已从系统中删除 . 发生这种情况时,msgrcv()函数返回,返回值为-1,errno设置为EIDRM .

  • 将信号传递给调用线程 . 发生这种情况时,msgrcv()函数返回,返回值为-1,errno设置为EINTR .

我的msgrcv函数不会等待 . 我在下面创建了一个最小,完整且可验证的示例 .

(另请注意,我没有运行任何其他可能使用mtype = 1拦截此消息的伴随程序,并在测试此程序时发回另一条mtype = 4的消息) .

#include <sys/msg.h>
#include <iostream>
using namespace std;

int main() {
    int qid = msgget(ftok(".",'u'), IPC_EXCL|IPC_CREAT|0600);
    struct buf {
        long mtype; // required
        int message; // mesg content
    };
    buf msg;
    int size = sizeof(msg)-sizeof(long);

    msg.mtype = 1;
    msgsnd(qid, (struct msgbuf *)&msg, size, 0); // sending
    cout << msg.message << endl;
    //Get acknowledgement from receiverA
    msgrcv(qid, (struct msgbuf *)&msg, size, 4, 0); // read mesg
    cout << msg.message << endl;
}

更新:

msgrcv函数返回的errno值为22(EINVAL),根据文档的含义,“MessageQueueID参数不是有效的消息队列标识符” .

所以我继续检查我的msgget函数的errno值是什么 . msgget函数返回值17(EEXIST) . 不知道如何处理这个但是msgget()的文档说“如果msgflg指定了IPC_CREAT和IPC_EXCL以及密钥已经存在消息队列,那么msgget()将失败并且errno设置为EEXIST . ”

只是搞乱了msgget函数,如果我更改第二个参数,在ftok函数中生成一个不同的标识符,它只能在我运行一次时,如果我尝试再次使用相同的标识符运行它,错误返回 . 所以我想我的问题可以简化为:我如何获得我想要使用的消息队列的qid但是如果它已经存在则不尝试生成它?

2 回答

  • 1

    从手册页:

    如果msgflg同时指定了IPC_CREAT和IPC_EXCL,并且密钥已存在消息队列,则msgget()将失败,并将errno设置为EEXIST .

    当我第一次尝试执行你的代码时,它在msgrcv()上被阻止,但是当我重新执行它时却没有 . 因为在下一次迭代中,msgget()失败了,EXIST和qid填充了-1 . 由于这个msgsnd()以及msgrcv()因无效参数而失败 .

    解决上述问题的方法是删除消息队列,在从测试程序返回之前使用msgctl()删除消息队列id,如下所示:

    msgctl(qid,IPC_RMID,NULL);

    建议:始终检查系统调用的返回值 .

    希望这会帮助你 .

  • 1

    尝试在调用 msgget 时删除 IPC_EXCL .

    来自 https://www.tldp.org/LDP/lpg/node34.html

    IPC_EXCL与IPC_CREAT一起使用时,如果队列已存在则失败 .

相关问题