该程序应该创建固定数量的子代(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;
}
}
答案 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>