消息队列问题

时间:2019-08-16 16:18:20

标签: c multithreading

该程序应该创建固定数量的子代(30),并且这些线程应该相互通信,以达到我可能稍后解释的目的。发生错误22:msgsnd和msgrcv行上的参数均无效。 抱歉,这是我第一次尝试在C中使用消息队列。

现在,我希望父亲首先给孩子发送有关偏好号的消息,每个孩子都应该收到该偏好并将其写入称为 vettorestudenti该信息。在开始做其他事情之前,我必须先解决这个问题

在定义区域的开头有一个测试代码:



there are some structs:
 struct dati{
        pid_t sender;
        int preferenza;// the father writes a preference number in a queue that should be read by children threads
    };
    struct msgbuf {
            long mtype; //pid destinatario 
            struct dati msglist;

        };
 struct tipostudente { //array that contains info about child process

    int matricola; // ID
    int voto_AdE; //student mark
    int numeroinviti; //number of invitations
    int preferenzaGruppo; // preference
    };
    pid_t *studenti;
//FOLLOW UPDATED CODE
 struct msgbuf coda[POP_SIZE];
    int queue_id = msgget(MY_KEY, IPC_CREAT | IPC_EXCL| 0666);
    if(queue_id==-1)
    { perror("error msgget"); }

many rows after
 /* vector of kids PIDs */
    studenti = malloc(POP_SIZE*sizeof(*studenti));
for(int u=0; u<POP_SIZE; u++)
        {
            coda[u].mtype=studenti[u];// qui il pid del destinatario
            coda[u].msglist.preferenza= funzionesceltaGrp();
            printf("funzpref22 %d  and studenti[u]= %lu \n",coda[u].msglist.preferenza, coda[u].mtype);
            if (msgsnd(queue_id, &coda[u], sizeof(coda[u])-sizeof(long), 0) == -1) 
            {

                perror("error msgsnd"); //INVALID ARGUMENT ERROR HERE

            }

        }


    for (i=0; i<POP_SIZE; i++) {//POP_SIZE volte esegue la fork
        switch (studenti[i] = fork()) {
        case -1:
            /* Handle error */
            fprintf(stderr, "%s, %d: Errore (%d) nella fork\n",
                __FILE__, __LINE__, errno);
            exit(EXIT_FAILURE);
        case 0: 
            srand(getpid());
            vettorestudenti[i].matricola=rand()%999999; 

            if (msgrcv(queue_id, &coda[i], sizeof(coda[i])-sizeof(long),0, 0) == -1) 
            {

                perror("error msgrcv"); //INVALID ARGUMENT ERROR HERE
            }
            printf("messaggio ricevuto, sono lo studente %d \n",vettorestudenti[i].matricola);




            free(studenti); 
            exit(0); 

            break; //FINE CODICE STUDENTE
        default:
            //codice del padre 


            break;  

        }
    }

1 个答案:

答案 0 :(得分:5)

您滥用errno。您假设它具有非零值,则表明存在错误,这是不正确的。 errno仅指示从库函数返回实际错误条件之后的错误。在没有通过其他方式给出肯定错误指示的情况下,errno本身的值是没有意义的。

请参见C标准的7.5 Errors , paragraph 4

  

程序启动时,初始线程中的errno值为零(其他线程中的errno的初始值是不确定的值),但任何库函数都不会将其设置为零。 errno的值可以通过库函数调用是否设置为非零值来确定是否存在错误,前提是本国际标准的功能描述中未记录errno的使用。

例如:

int queue_id = msgget(MY_KEY, IPC_CREAT | IPC_EXCL| 0666);
TEST_ERROR;

该代码假定 errno的值非零表示错误。它不是。根据{{​​3}}:

  

返回值

     

成功完成后,msgget()将返回一个非负整数,即消息队列标识符。否则,它将返回-1并设置errno来指示错误。

errno仅在msgget()之后用来表示发生了什么错误,当且仅当 msgget()已经返回-1时。< / p>