2009-08-16 3 views
3

Я использую очередь IPC для выполнения синхронизации процесса.Ошибка идентификации идентификатора (EIDRM) при отправке сообщения с очередью IPC

Я всегда получаю EIDRM eror при отправке принимающих сообщений из очереди IPC, но я вижу, что очередь там с ipcs.

Я искал 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; 

}

ответ

4

Проблема заключается в неправильном обращении с precedence and order of evaluation in C всякий раз, когда вы оценить возвращаемое значение msgget от значений ниже 0:

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

старшинство оператора присваивания = падает ниже сравнения одного <, который подразумевает, что вы присваивали результат msgget() < 0 msgqid и не проверяли, (msgqid = msgget()) < 0.

Затем вы должны окружать задание со скобками:

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

Просто некоторые идеи,

Вы должны проверить msgget() против -1, чтобы проверить, если это не удалось.

EIDRM означает «Идентификатор удален», поэтому он согласуется с тем, что вы видите в ipcs.

Возможно, во-первых, вы хотите, чтобы очередь была создана (см. Ipcs), и только после этого продолжайте отправлять/получать сообщения.

+0

уже я проверка msgget и кажется правильным. Я не уверен, что вы понимаете, что вы имеете в виду, что «идентификатор удаления» соответствует «ipcs», когда ipcs сообщает мне, что очередь создана. – Nodens

0

Оставляет ли очередь сообщений, когда вы убиваете этот процесс? То есть, вы работаете со свежей очередью каждый раз, когда вы проверяете? Мне любопытно, действительно ли разрешения - это то, что вы думаете.

Кроме того, как насчет публикации компилируемой части кода, которая дает вам ошибку. Я хотел бы посмотреть, какие файлы вы включили.

+0

Да, я работаю с новой очередью каждый раз, когда я тестирую, очередь не исчезает, когда я убиваю процесс, я убиваю его вручную с помощью ipcrm. Позже я опубликую весь код. – Nodens

+0

Хорошо. Это странно. Программа работает в первый раз, когда я ее выполняю. В первый раз, когда я запускаю программу, создается очередь сообщений с msqid 0. Прямо сейчас, программа не заканчивается должным образом, поэтому очередь не будет правильно уничтожена программой, я должен ее уничтожить с помощью ipcrm -q. После этого каждый раз, когда я заново запускаю программу, я получаю ошибки EIDRM. Ipcs говорит, что theres создана очередь, но теперь с другим msqid. Кажется, что проблемы возникают из-за не закрытия очереди правильно, но я удивляюсь, почему это делает последующие прогоны, даже с разным ключом ipc, сбой. – Nodens

0

Хорошо. Одно обновление проблемы.

В первый раз, когда я запускаю программу, она работает отлично. Если я использую ipcs, я вижу, что программа создает очередь с msqid 0. Программы удаляют очередь без проблем.

После первого запуска он перестает работать и начинает выдавать ошибку EIDRM, ipcs говорит, что создала очередь, но у нее нет msqid 0, как и первый запуск, его случайное число. Это происходит, даже если я меняю ipckey, он просто создает очередную очередь с другим msquid и не работает таким же образом.

1

Проблема решена.

Я всегда получал 0 в качестве id очереди, потому что я вызывал msgget внутри условия if. Я достал msgget и делал if с переменной прекрасно работает.

Смежные вопросы