簡體   English   中英

IPC隊列msgsnd錯誤

[英]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
  • 所以它一定是無效的msqid!

當你看

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM