msgrcv 中的错误:参数无效

Posted

技术标签:

【中文标题】msgrcv 中的错误:参数无效【英文标题】:Error in msgrcv: Invalid Arguments 【发布时间】:2009-10-18 20:54:58 【问题描述】:

我正在 unix 系统上用 C 语言编写代码。我创建了一个消息队列服务器。每次我收到一条新消息时,我都会分叉,子进程会处理新客户端。服务器等待新的客户端。这是代码。

for (;;)
 
      struct my_msgbuf buf;

      if (msgrcv (msqid, &(buf.mtype), sizeof (buf), 1, 0) == -1)
      perror ("msgrcv");


    if((pid = fork())<0)
    perror("fork");


    if(pid==0)
    
     //child code
    

现在代码适用于第一次迭代,但在第二次迭代时 msgrcv 给出以下错误 - msgrcv:参数无效,而不是等待新消息。

【问题讨论】:

【参考方案1】:

msgrcv 确实有一个msgsz 参数,但它不是struct my_msgbuf 的大小,而是结构的mtext[] 字段中的字节数。

我认为你不应该直接使用struct msgbuf。用适当的空间定义你自己的是正常的。按照你的方式,你的 buf 声明只分配 1 个字节,然后代码告诉内核你有 sizeof buf 字节,而你没有。因此,代码会调用 Undefined Behavior 或 UB。

这可能会或可能不会解释EINVAL,但应该始终修复已知错误并重新测试,因为 UB 污染了进一步的分析......

【讨论】:

代码没有显示分配给mtype。设置合理吗? 当然,但是您是否设置为一个正数来标识队列中的消息类型?不确定您使用的是什么 Unix,但在我的 linux 手册页上关于 EINVAL 的来源有以下说明:无效的 msqid 值,或非正 mtype 值,或无效的 msgsz 值(小于 0 或大于系统值 MSGMAX )。【参考方案2】:

上面的代码几乎没有问题。首先在这里

msgrcv (msqid, &(buf.mtype), sizeof (buf), 1, 0)

第二个参数&amp;(buf.mtype) 不正确,因为进程预计会收到完整的buf 而不仅仅是buf.mtype。如果struct my_msgbuf 看起来像

struct my_msgbuf 
       long mtype;       /* message type, must be > 0 */
       char mtext[1];    /* message data */

;

那么msgrcv() 应该是这样的

msgrcv (msqid, &buf, sizeof(buf), 1, 0);

现在代码适用于第一次迭代,但适用于第二次迭代 msgrcv 给出以下错误 - msgrcv: Invalid Arguments instead 等待新消息?

那是因为msgrcv()fork()之前执行,如果父进程没有执行msgsnd()怎么办?

要解决这个问题,您应该在子进程中保留msgrcv() 语句。还要在子和父进程内而不是在子/父块之外运行 for 循环。例如

struct my_msgbuf buf;

if((pid = fork())<0)

    /* @TODO set the buf.mtype here  */
    perror("fork");
    for(;;) /* use loop inside parent process to write into MQ continuously */
    
        /* @TODO scan the data into  buf.mtext */
        /* @TODO msgsnd statement */
    

else

    for(;;) /* use loop inside child process to read from MQ continuously */
    
        if (msgrcv (msqid, &buf, sizeof (buf), 1, 0) == -1)
            perror ("msgrcv");
        printf("received data : %s\n", buf.mtext);
    

【讨论】:

msgrcv 需要 sizeof(struct) - sizeof(long)。

以上是关于msgrcv 中的错误:参数无效的主要内容,如果未能解决你的问题,请参考以下文章

facebook 发送 API 错误代码:100 API 错误描述:无效参数错误消息:“链接”无效

从设备到主机的 cudaMemcpy 中的参数无效错误

ls(envir = envir, all.names = private) 中的错误:R 中的“envir”参数无效

向量中的错误(“列表”,n.chains):无效的“长度”参数

代表错误:无效的“次”参数

安装失败:参数无效 - 系统错误