msgrcv: Invalid ошибки Аргумент

Обновить

April 2019

Просмотры

3.6k раз

1

Я получаю сообщение об ошибке, которая говорит:

msgrcv: Недопустимый аргумент

что может быть причиной этой ошибки? Вот мой код

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

    struct msg {
        long int    mtype;      /* message type */
        char        mtext[1024];   /* message text */
} msg;
int len, msgflg = 0, msqid, *pint;
pid_t pid;
size_t msgsz = 40;
long int msgtyp;
msqid = msgget(IPC_PRIVATE,S_IRWXU);
char* charpid[250];
msg.mtype = 1;
if (msqid < 0) {
        perror("msgget");
        exit(1);
}

switch(pid=fork()) //fork child process
{
case 0: //Child process 

    //receive message from parent
    if(msgrcv(msqid,&msg,sizeof msg.mtext, 1,IPC_NOWAIT)>=0){
        printf("Serving for client pid #%s",msg.mtext);         
        asprintf(&charpid[0], "%ld\n", pid);
        strncpy(msg.mtext,charpid[0], 1024);

        if(msgsnd(msqid,&msg,strlen(msg.mtext),msgflg)<0){
            perror("msgsnd");       
        }
    }
    else
        perror("msgrcv");

    msgctl(msqid, IPC_RMID, NULL);
    exit(0);

case -1:
    printf("fork failed");
    exit(2);
    break;
default:
    //convert pid to string.
    asprintf(&charpid[0], "%ld\n", pid);
    //set mtext
    strncpy(msg.mtext,charpid[0], 1024);
    //send message

    if(msgsnd(msqid,&msg,strlen(msg.mtext),msgflg)<0){
        //report error
        perror("msgsnd");
    }
    //wait for child process to die
    wait(NULL); 
    //receive message from child
    if(msgrcv(msqid,&msg,sizeof msg.mtext, msg.mtype,IPC_NOWAIT)>=0){
        //print pid
        printf("Received reply from pid #%s",msg.mtext);
    }
    else

        //report error
        perror("msgrcv");   
    exit(0);
}

1 ответы

4

The "Invalid argument" error is from your original process (not the forked child), and occurs when it tries to receive the reply from the child. The error occurs because the child has already removed the queue by then. Since your original process created the queue and waits for the child to exit anyway, it would make more sense to remove the queue there (after receiving the reply).

Even if you fix that, you may still find that when the child does its msgrcv it might not get anything, since your original process may not have sent it yet (and you specify IPC_NOWAIT). To get your code to work, with both receives, I had to move the msgctl call as noted above, and also add a sleep call before the msgrcv in the child.