[英]IPC Queue msgsnd error
這是一個將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");
}
}
}
我做錯了什么?
你查看了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
的調用出了什么問題。 這也可以用於任何其他系統調用。
根據手冊“無效參數”( 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 當你看
if(id = msgget(1234, IPC_CREAT | 0666) < 0)
你會看到周圍缺少的括號(id = msgget(...))
。 很可能msgget
返回的值> 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) {
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.