简体   繁体   English

这是消息队列应该如何工作的吗?

[英]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 . 在我看到的示例中, msg strunct除了第一个属性(类型)必须为long之外,还只有一个属性。 So, it would be something like struct msg{long mtype; char text[100]}; 因此,它将类似于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. 我尝试添加一个新的int属性x以查看我是否同时接收到文本和数字,并且该方法有效。

Is this how message queues are supposed to work? 这是消息队列应该如何工作的吗? Can I have as many attributes as I want in my struct ? 我可以在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? 并且,也可以通过将length参数设置为sizeof(send) - sizeof(send.x)来调用msgrcvmsgsnd函数,因为我知道结构的大小并不总是与每个属性的sizeof 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: msgp定义为:

The msgp argument is a pointer to a caller-defined structure of the following general form: msgp参数是指向以下一般形式的调用方定义的结构的指针:

  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 . 这里最重要的是struct是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). 因此,只要输入结构(由msgsnd发送)和输出结构(由msgrcv接收)相同,则mtype的数据可以是您想要的任何内容(只要正确指定大小)。 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. char []只是一个占位符,在所需的长mtype字段之后,您可以在结构中拥有所需的任何内容。 The size on the msgsnd() call does NOT include mtype. msgsnd()调用的大小不包括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. 由于msgp参数声明为const void* ,因此您可以使用所需的任何数据类型。 There is nothing that says it has to be a struct with just a long and a char[] . 没有什么,说,它是一个struct ,只需longchar[] This means you can just do sizeof(send) . 这意味着您可以执行sizeof(send) You do not need to adjust for the extra struct member that you are sending. 您不需要调整要发送的额外的struct成员。 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() . 唯一重要的是msgrcv()使用与以前的msgsnd()相同的结构。 See this example . 请参阅此示例

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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