IPC队列msgsnd错误

时间:2016-11-02 17:07:23

标签: c ipc

这是一个将msg发送到队列的简单程序,但它会给出" snd error"作为输出。 队列已创建。我检查了ipcs -q。 我做错了什么?

#include<stdio.h>
#include<unistd.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<sys/types.h>
#include<stdlib.h>
struct msg{
int mtype;
char mtext[1024];

}snd;
void main()
{
int id;
if(id=msgget(1234,IPC_CREAT|0666)<0)
{
    printf("ipc error");
}
else{
    snd.mtype=1;
    scanf("%[^\n]",snd.mtext);
    getchar();

    if(msgsnd(id,&snd,sizeof(snd.mtext),IPC_NOWAIT)<0){
            printf("snd error");
    }
    else {
        printf("msg snd");
    }

}

}

1 个答案:

答案 0 :(得分:0)

  

我做错了什么?

您检查msgsnd的返回代码,这很好,这意味着,您已经领先于许多程序员。但是你还没有阅读msgsnd的整本手册,其中说明了

  

返回值
  失败时,两个函数都返回-1, errno 表示错误,

其中errno是重要的部分。

当你进一步观察时,还有一个名为ERRORS的部分,它显示了可能出错的部分

  

<强>错误
         当msgsnd()失败时,errno将被设置为以下之一          价值观:

  EACCES The calling process does not have write permission on the
          message queue, and does not have the CAP_IPC_OWNER capability.  

  EAGAIN The message can't be sent due to the msg_qbytes limit for the
          queue and IPC_NOWAIT was specified in msgflg.
     

...

更进一步,你会找到一个示例部分

  

示例

  The program below demonstrates the use of msgsnd() and msgrcv().  
     

...

msgsnd的使用显示了一个重要的习惯用法:当发生错误并在errno中报告了特定错误时,perror可能会打印出此错误

if (msgsnd(qid, (void *) &msg, sizeof(msg.mtext),
           IPC_NOWAIT) == -1) {
    perror("msgsnd error");
    exit(EXIT_FAILURE);
}

perror会显示一条消息,详细说明调用msgsnd时出现的问题。这也可以用于任何其他系统调用。

根据手册&#34;无效的参数&#34; (EINVAL)表示

之一
  

EINVAL msqid无效,或者msgsz小于0   EINVAL(自Linux 3.14起)msgflg指定了MSG_COPY,但没有指定IPC_NOWAIT。
  EINVAL(自Linux 3.14起)msgflg指定了MSG_COPY和MSG_EXCEPT。

由于您未指定MSG_COPY,因此错误必须是第一个错误。

  • msgsz肯定大于0
  • 所以它必须是无效的msqid!

当你看到

if(id = msgget(1234, IPC_CREAT | 0666) < 0)

你看到(id = msgget(...))周围缺少括号。最有可能msgget返回值&gt; 0,所以msgget(...) < 0为false,id将变为0(false),并且采用else分支。

因此,调用msgsnd(0, ...)很可能是错误的罪魁祸首和来源。

要解决此问题,请明确

id = msgget(1234, IPC_CREAT | 0666);
if (id < 0) {
...
} else {
...
}

或至少在作业周围添加括号

if ((id = msgget(1234, IPC_CREAT | 0666)) < 0) {