简体   繁体   中英

Is this how message queues are supposed to work?

I am trying to understand message queues. In the examples I saw, the msg strunct would have only one more attribute except of the first one (the type) which must be long . So, it would be something like struct msg{long mtype; char text[100]}; struct msg{long mtype; char text[100]}; .

I tried to add a new int attribute, x to see if I recieve both the text and the number and it worked.

Is this how message queues are supposed to work? Can I have as many attributes as I want in my struct ?

And, also, is it ok to call the msgrcv and msgsnd functions with the length parameter set to sizeof(send) - sizeof(send.x) because I know that the sizeof a struct isn't always the same as the sum of the sizeof of each attribute? Thank you.

int main(){

    struct msg{
        long mtype;
        char text[100];
        int x;
    };

    int key = ftok(".", 10);
    int qid = msgget(key, 0666|IPC_CREAT);

    int pid = fork();

    if(pid == 0){
        struct msg send;
        send.mtype = 1;
        strcpy(send.text, "hello");
        send.x = 99;
        if(msgsnd(qid, (void*)&send, sizeof(send) - sizeof(send.x), 0)<0){
             printf("Error child: ");
        }
    }
    else{
        struct msg recieve;
        if(msgrcv(qid, (void*)&recieve, sizeof(recieve) - sizeof(recieve.x), 1, 0)<0){
             perror("Error parent: ");
        };
        printf("text: %s\nnumber: %d", recieve.text, recieve.x);
    }

    return 0;
}

From the man page , in:

int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);

msgp is defined as:

The msgp argument is a pointer to a caller-defined structure of the following general form:

  struct msgbuf { long mtype; /* message type, must be > 0 */ char mtext[1]; /* message data */ }; 

Bold is mine

The major point here being the struct is caller-defined . So as long as the input struct (sent by msgsnd ) and output struct (received by msgrcv ) are the same, the data following mtype can be anything you want (as long as you specify the size correctly). For your case, you really only need:

msgsnd(qid, (void*)&send, sizeof(send) - sizeof(send.mtype), 0)

and

msgrcv(qid, (void*)&recieve, sizeof(recieve) - sizeof(send.mtype), 1, 0)

The char[] is just a placeholder, you can have whatever you want in the structure after the required long mtype field. The size on the msgsnd() call does NOT include mtype.

You almost had it correct.

Here is a working version:

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

int main(void){

    struct msg {
        long mtype;
        char text[100];
        int x;
    };

    size_t sz = sizeof(struct msg) - sizeof(long);  <=== /* SIZE */
    int key = ftok(".", 10);
    int qid = msgget(key, 0666|IPC_CREAT);

    int pid = fork();

    if (pid == 0){
        struct msg send;
        send.mtype = 1;
        strcpy(send.text, "hello");
        send.x = 99;
        if (msgsnd(qid, (void*)&send, sz, 0)<0){
             perror("Error child: ");
        }
    } else {
        struct msg recieve;
        if(msgrcv(qid, (void*)&recieve, sz, 1, 0)<0){
             perror("Error parent: ");
        };
        printf("text: %s\nnumber: %d\n", recieve.text, recieve.x);
    }

    return 0;
}
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);

Since the msgp parameter is declared as const void* , you can use whatever data type you want. There is nothing that says it has to be a struct with just a long and a char[] . This means you can just do sizeof(send) . You do not need to adjust for the extra struct member that you are sending. In fact, doing so will cause problems because the entire struct will not be handled. The only thing that matters is that msgrcv() uses the same struct as the previous msgsnd() . See this example .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM