2009-08-16 11 views
3

Ich verwende eine IPC-Warteschlange, um Prozesssynchronisierung durchzuführen.Identifier Removed (EIDRM) Fehler beim Senden einer Nachricht mit einer IPC-Warteschlange

Ich bekomme immer den EIDRM-Fehler, wenn ich eine empfangene Nachricht von einer IPC-Warteschlange sende, aber ich kann sehen, dass die Warteschlange mit ipcs da ist.

Ich war für 2 Stunden suchen, aber ich kann den Fehler nicht sehen.

Der folgende Code ist eine abgespeckte Version, die mir den gleichen Fehler gibt.

#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; 

}

Antwort

4

Das Problem liegt in der unsachgemäßen Handhabung der precedence and order of evaluation in C, wenn Sie den msgget Rückgabewert gegen Werte unter 0 bewerten:

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

Der Vorrang des Zuweisungsoperators = fällt unter dem Vergleich eines <, die Impliziert, dass Sie das Ergebnis von msgget() < 0 msgqid zugewiesen haben und nicht prüfen, ob (msgqid = msgget()) < 0.

Sie sollten dann umgeben die Zuordnung mit Klammern:

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

nur einige Ideen,

sollten Sie überprüfen msgget() gegen -1 überprüfen, ob es fehlgeschlagen.

EIDRM steht für "Identifier removed", also entspricht es dem, was Sie in ipcs sehen.

Vielleicht möchten Sie zuerst sicherstellen, dass die Warteschlange erstellt wird (siehe ipcs) und erst danach Nachrichten senden/empfangen.

+0

ich schon von msgget tun Kontrolle und scheint richtig. Ich bin nicht sicher zu verstehen, was Sie meinen, dass "Kennung entfernen" mit "ipcs" konsistent ist, wenn ipcs sagt mir, dass die Warteschlange erstellt wird. – Nodens

0

Verliert die Nachrichtenwarteschlange, wenn Sie diesen Prozess beenden? Das heißt, arbeiten Sie bei jedem Test mit einer neuen Warteschlange? Ich bin neugierig, ob die Berechtigungen tatsächlich sind, was Sie denken, sie sind.

Wie wäre es mit der Veröffentlichung eines kompilierbaren Codes, der den Fehler verursacht? Ich würde gerne sehen, welche Dateien Sie einschließen.

+0

Ja, ich arbeite jedes Mal mit einer neuen Warteschlange, die Warteschlange verschwindet nicht, wenn ich den Prozess abbringe, ich töte es manuell mit ipcrm. Später werde ich den ganzen Code veröffentlichen. – Nodens

+0

Ok. Das ist seltsam. Das Programm funktioniert das erste Mal, wenn ich es ausführe. Beim ersten Ausführen des Programms wird eine Nachrichtenwarteschlange mit msqid 0 erstellt. Im Moment wird das Programm nicht richtig beendet, so dass die Warteschlange nicht richtig vom Programm zerstört wird, ich muss es mit ipcrm -q zerstören. Danach, jedes Mal, wenn ich das Programm erneut ausführen, bekomme ich die EIDRM-Fehler. Ipcs sagt, dass Theres eine Warteschlange erstellt wurde, aber jetzt mit einer anderen msqid. Scheint, dass die Probleme entstehen, die Warteschlange nicht korrekt zu schließen, aber ich frage mich, warum das nachfolgende Läufe, sogar mit einem anderen IPC-Schlüssel, fehlschlagen. – Nodens

0

Ok. Ein Update über das Problem.

Das erste Mal, wenn ich das Programm starte, funktioniert es perfekt. Wenn ich ipcs verwende, kann ich sehen, dass das Programm eine Warteschlange mit msqid 0 erstellt. Das Programm löscht die Warteschlange ohne Probleme.

Nach dem ersten Lauf, hört es auf zu arbeiten und fängt an, den EIDRM Fehler zu geben, ipcs sagt, dass es eine Warteschlange erstellt, aber es hat keine msqid 0 wie der erste Lauf, es ist eine Zufallszahl. Dies passiert, selbst wenn ich den ipckey ändere, es erstellt nur eine andere Warteschlange mit einem anderen msquid und schlägt auf die gleiche Weise fehl.

1

Problem gelöst.

Ich bekam immer 0 als ID der Warteschlange, weil ich msgget innerhalb der If-Bedingung aufgerufen habe. Ich nahm das msgget heraus und mache das if mit der Variablen gut.