Reputation: 57
this program should create a fixed number of childs (30), and these threads should communicate each other for purposes that maybe I can explain after. occurs the error 22: invalid arguments both on msgsnd and msgrcv lines. sorry this is the first time I try to use the messages queues in C
for now I want that the father first send to child a message about a preference number, every child should receive it and write in the array called vettorestudenti this info. before starting do other things I have to fix this
there is a test code at the beginning in the define area:
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;
}
}
Upvotes: 0
Views: 522
Reputation: 1
You are misusing errno
. You are assuming if it has a non-zero value it indicates an error, which is not true. errno
merely indicates what the error was after an actual error condition was returned from a library function. In the absence of positive error indication by other means, the value of errno
itself is meaningless.
See 7.5 Errors , paragraph 4 of the C standard:
The value of errno in the initial thread is zero at program startup (the initial value of errno in other threads is an indeterminate value), but is never set to zero by any library function. The value of errno may be set to nonzero by a library function call whether or not there is an error, provided the use of errno is not documented in the description of the function in this International Standard.
For example:
int queue_id = msgget(MY_KEY, IPC_CREAT | IPC_EXCL| 0666);
TEST_ERROR;
That code assumes a non-zero value for errno
indicates an error. It does not. Per the POSIX msgget()
documentation:
RETURN VALUE
Upon successful completion,
msgget()
shall return a non-negative integer, namely a message queue identifier. Otherwise, it shall return-1
and seterrno
to indicate the error.
errno
's only use after msgget()
is to indicate what error happened if and only if msgget()
has already returned -1
.
Upvotes: 5