使用IPC队列发送消息时出现标识符已删除(EIDRM)错误

使用IPC队列发送消息时出现标识符已删除(EIDRM)错误,c,ipc,message-queue,C,Ipc,Message Queue,我正在使用IPC队列进行进程同步 当从IPC队列发送接收消息时,我总是得到EIDRM eror,但我可以看到队列中有IPC 我已经搜索了2个小时,但我看不到错误 下面的代码是一个精简版本,它给出了相同的错误 #define CLAVE 53543961 #define TAM_BUFFER 1024 #define PERMISOS 0777 #define DEBUG int Cola_Mensages; int msgqid; typedef struct { long mt

我正在使用IPC队列进行进程同步

当从IPC队列发送接收消息时,我总是得到EIDRM eror,但我可以看到队列中有IPC

我已经搜索了2个小时,但我看不到错误

下面的代码是一个精简版本,它给出了相同的错误

#define CLAVE 53543961
#define TAM_BUFFER 1024
#define PERMISOS 0777
#define DEBUG

int Cola_Mensages;
int msgqid;


typedef struct  {
    long mtype;
    char mtext[TAM_BUFFER];
}msgbuf;


int main (int argc, char *argv[]){
    msgbuf msg_ipc;
    int num_cli,i, i_aux;

    if(argc == 2){
    num_cli = atoi(argv[1]);
    }else{ 
    num_cli = 1;
    }


    //Creating the queue
    if(msgqid = msgget(CLAVE,PERMISOS|IPC_CREAT)<0){
        fprintf(stderr,"Problema al crear la cola de mensages IPC\n");
        exit(0);
    }

    if(msgqid < 0){
        fprintf(stderr,"Problema al crear la cola de mensages IPC\n");
        exit(0);
    }


    for(i = 0;i<num_cli;i++){
       //here i get the error
       i_aux=msgrcv(msgqid,&msg_ipc,TAM_BUFFER,1,0);
       if(i_aux == -1)
           fprintf(stderr,"Error enviando msg ipc %s \n",strerror(errno));
       }

    msg_ipc.mtype = 2;
    strcpy(msg_ipc.mtext,"COMIENZO");
    printf("Enviando msg\n");

       for(i = 0;i<num_cli;i++){
           printf("Enviado msg %d\n",i);
       //here i also get the same error
           if (msgsnd(msgqid,(char *) &msg_ipc,strlen(msg_ipc.mtext),0)!=0)
           {
              fprintf(stderr,"Ocurrio el error %s en msgsnd\n",strerror(errno));
              exit(4);
           }
       }   


    if (msgctl(msgqid,IPC_RMID,(struct msqid_ds *) NULL)<0)
    {
       fprintf(stderr,"Error al borrar la cola de mensajes de clave %d\n",CLAVE);
       exit(4);
    }

    return 0;
#定义CLAVE 53543961
#定义TAM_缓冲区1024
#定义PERMISOS 0777
#定义调试
int Cola_尺寸;
int-msgqid;
类型定义结构{
长型;
字符多行文字[TAM_BUFFER];
}msgbuf;
int main(int argc,char*argv[]){
msgbuf msg_ipc;
int num_cli,i,i_aux;
如果(argc==2){
num_cli=atoi(argv[1]);
}否则{
num_cli=1;
}
//创建队列
如果(msgqid=msgget(CLAVE,PERMISOS | IPC_CREAT)只是一些想法

您应该对照-1检查msgget()以检查它是否失败

EIDRM代表“标识符已删除”,因此它与您在ipcs中看到的一致


首先,您可能希望确保创建了队列(请参见ipcs),然后才能继续发送/接收消息。

当您终止此进程时,消息队列是否会消失?也就是说,您是否每次测试时都使用新的队列?我很好奇权限是否与您想象的一样


另外,发布一段导致错误的可编译代码如何。我想看看您包含了哪些文件。

好的。关于此问题的一个更新

我第一次运行该程序时,它工作得非常好。如果我使用ipcs,我可以看到该程序创建了一个msqid为0的队列。程序删除该队列时不会出现任何问题

在第一次运行后,它停止工作并开始给出EIDRM错误,ipcs说创建了一个队列,但它没有msqid 0,就像第一次运行一样,它是一个随机数。即使我更改ipckey,也会发生这种情况,它只会创建另一个具有不同msquid的队列,并以同样的方式失败。

问题已解决


我总是将0作为队列的id,因为我在if条件内调用msgget。我取出msgget并使用变量执行if工作正常。

问题在于对的处理不正确,每当您根据低于0的值评估msgget返回值时:

if(msgqid = msgget(CLAVE,PERMISOS|IPC_CREAT)<0){
    fprintf(stderr,"Problema al crear la cola de mensages IPC\n");
    exit(0);
}

if(msgqid=msgget(CLAVE,PERMISOS | IPC|u CREAT)我已经对msgget进行了检查,似乎是正确的。我不确定是否理解“标识符删除”是什么意思当ipcs告诉我队列已创建时,与“ipcs”一致。是的,我每次测试时都使用一个新队列,当我终止进程时,队列不会消失,我使用ipcrm手动终止它。稍后我将发布整个代码。好的。这很奇怪。程序在我第一次执行它时工作。第一次执行程序时,一个mes创建了msqid为0的sage队列。现在,程序没有正确结束,因此该队列没有被程序正确销毁,我必须使用ipcrm-q销毁它。之后,每次我重新运行该程序时,我都会收到EIDRM错误。Ipcs说创建了一个队列,但现在使用了不同的msqid。似乎问题已经解决了由于没有正确关闭队列,我想知道为什么即使使用不同的ipc密钥,后续运行也会失败。
if((msgqid = msgget(CLAVE, PERMISOS | IPC_CREAT)) < 0){
    fprintf(stderr,"Problema al crear la cola de mensages IPC\n");
    exit(0);
}