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)
第二个参数&(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 错误描述:无效参数错误消息:“链接”无效
ls(envir = envir, all.names = private) 中的错误:R 中的“envir”参数无效