msgrcv中的错误:无效的参数

时间:2009-10-18 20:54:59

标签: c unix ipc

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

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:参数无效,而不是等待新消息。

2 个答案:

答案 0 :(得分:0)

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

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

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

答案 1 :(得分:0)

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

reshape

第二个自变量msgrcv (msqid, &(buf.mtype), sizeof (buf), 1, 0) 是错误的,因为预期过程不仅会收到&(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给出以下错误-msgrcv:无效参数   等待新消息?

这是因为msgrcv (msqid, &buf, sizeof(buf), 1, 0); msgrcv()之前执行,如果父进程未执行fork()会怎样?

要解决此问题,您应在子进程中保留msgsnd()语句。还要在子进程和父进程内部而不是子/父块外部运行for循环。对于例如

msgrcv()