这是消息队列应该如何工作的吗?
Is this how message queues are supposed to work?
我正在尝试了解消息队列。在我看到的示例中,msg
结构除了第一个属性(类型)必须是 long
之外,只有一个属性。所以,它会类似于 struct msg{long mtype; char text[100]};
。
我尝试添加一个新的 int
属性,x
以查看我是否同时收到文本和数字并且它有效。
消息队列应该是这样工作的吗?我可以在 struct
中拥有任意数量的属性吗?
此外,调用长度参数设置为 sizeof(send) - sizeof(send.x)
的 msgrcv
和 msgsnd
函数是否可以,因为我知道结构的大小并不总是等于每个属性的sizeof
之和?
谢谢。
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;
}
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
由于 msgp
参数被声明为 const void*
,您可以使用任何您想要的数据类型。没有什么说它必须是 struct
,只有 long
和 char[]
。这意味着你可以做 sizeof(send)
。您不需要为发送的额外结构成员进行调整。事实上,这样做会导致问题,因为不会处理整个结构。唯一重要的是 msgrcv()
使用与之前的 msgsnd()
相同的结构。参见 this example。
来自 man page,在:
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
msgp
定义为:
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 */
};
粗体是我的
这里的要点是结构caller-defined。所以只要输入结构(由msgsnd
发送)和输出结构(由msgrcv
接收)相同,mtype
后面的数据可以是任何你想要的(只要你正确指定尺寸)。对于你的情况,你真的只需要:
msgsnd(qid, (void*)&send, sizeof(send) - sizeof(send.mtype), 0)
和
msgrcv(qid, (void*)&recieve, sizeof(recieve) - sizeof(send.mtype), 1, 0)
char[]只是一个占位符,你可以在需要的long mtype字段之后的结构中有任何你想要的。 msgsnd() 调用的大小不包括 mtype。
你几乎答对了。
这是一个工作版本:
#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;
}
我正在尝试了解消息队列。在我看到的示例中,msg
结构除了第一个属性(类型)必须是 long
之外,只有一个属性。所以,它会类似于 struct msg{long mtype; char text[100]};
。
我尝试添加一个新的 int
属性,x
以查看我是否同时收到文本和数字并且它有效。
消息队列应该是这样工作的吗?我可以在 struct
中拥有任意数量的属性吗?
此外,调用长度参数设置为 sizeof(send) - sizeof(send.x)
的 msgrcv
和 msgsnd
函数是否可以,因为我知道结构的大小并不总是等于每个属性的sizeof
之和?
谢谢。
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;
}
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
由于 msgp
参数被声明为 const void*
,您可以使用任何您想要的数据类型。没有什么说它必须是 struct
,只有 long
和 char[]
。这意味着你可以做 sizeof(send)
。您不需要为发送的额外结构成员进行调整。事实上,这样做会导致问题,因为不会处理整个结构。唯一重要的是 msgrcv()
使用与之前的 msgsnd()
相同的结构。参见 this example。
来自 man page,在:
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
msgp
定义为:
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 */ };
粗体是我的
这里的要点是结构caller-defined。所以只要输入结构(由msgsnd
发送)和输出结构(由msgrcv
接收)相同,mtype
后面的数据可以是任何你想要的(只要你正确指定尺寸)。对于你的情况,你真的只需要:
msgsnd(qid, (void*)&send, sizeof(send) - sizeof(send.mtype), 0)
和
msgrcv(qid, (void*)&recieve, sizeof(recieve) - sizeof(send.mtype), 1, 0)
char[]只是一个占位符,你可以在需要的long mtype字段之后的结构中有任何你想要的。 msgsnd() 调用的大小不包括 mtype。
你几乎答对了。
这是一个工作版本:
#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;
}