msgsnd()和msgrcv()在同一个函数中,其工作原理与第一个示例类似。
主C
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
int main(int argc, char *argv[])
{
pid_t pid1;
pid_t pid2;
pid_t pid3;
pid_t pid4;
if ((pid1 = fork()) < 0) {
printf("fork error\n");
} else if (pid1 == 0){
printf("I am in First process\n");
int nodeId = 1;
//cmc_init(nodeId);
test2(nodeId);
return 0;
}
if ((pid2 = fork()) < 0) {
printf("fork error\n");
} else if (pid2 == 0){
printf("I am in second process\n");
int nodeId = 2;
//cmc_init(nodeId);
test2(nodeId);
return 0;
}
if ((pid3 = fork()) < 0) {
printf("pid3 fork error\n");
} else if (pid3 == 0) {
printf("I am in Third process\n");
int nodeId = 3;
//cmc_init(nodeId);
test2(nodeId);
return 0;
}
if ((pid4 = fork()) < 0) {
printf("pid4 fork error\n");
} else if (pid4 == 0) {
printf("I am in Fourth process\n");
int nodeId = 4;
//cmc_init(nodeId);
//test2(nodeId);
return 0;
}
if (waitpid(-1, NULL, 0) < 0) {
printf("wait1 error\n");
}
sleep(3);
return 0;
}
压缩机C
typedef struct Msg_context {
int nodeId;
} Msg_context;
void test2(int nodeId)
{
int i = 1;
for (i = 1; i <= 3; i++) {
if (i == nodeId) {
continue;
}
int msgid = -1;
Msg_context msgSend;
msgid = msgget((key_t)i, 0666 | IPC_CREAT);
if (msgid == -1) {
printf("msgid == -1\n");
}
msgSend.nodeId = nodeId;
if (msgsnd(msgid, (void *)&msgSend, 4, 0) == -1) {
printf("send message error\n");
}
}
//com_process_send(nodeId);
sleep(1);
while (1) {
//com_process_recv(nodeId);
int msgrecvId = -1;
Msg_context msgRecv;
msgrecvId = msgget((key_t)nodeId, 0666 | IPC_CREAT);
if (msgrecvId == -1) {
printf("msgrecvId == -1\n");
}
if (msgrcv(msgrecvId, (void *)&msgRecv, BUFSIZ, 0, 0) == -1) {
printf("send message error\n");
}
printf("[recv] nodeId = %d, recv.nodeId = %d\n", nodeId, msgRecv.nodeId);
}
}
效果很好,结果是:
I am in First process
[recv] nodeId = 2, recv.nodeId = 1
[recv] nodeId = 3, recv.nodeId = 1
I am in second process
[recv] nodeId = 1, recv.nodeId = 2
[recv] nodeId = 3, recv.nodeId = 2
I am in Third process
[recv] nodeId = 1, recv.nodeId = 3
[recv] nodeId = 2, recv.nodeId = 3
I am in Fourth process
但是,当我将msgrcv()放入另一个函数时,它不会很好地工作。
这样地:
压缩机C
typedef struct Msg_context {
int nodeId;
} Msg_context;
int com_process_recv(int nodeId)
{
int msgrecvId = -1;
Msg_context msgRecv;
msgrecvId = msgget((key_t)nodeId, 0666 | IPC_CREAT);
if (msgrecvId == -1) {
printf("msgrecvId == -1\n");
}
if (msgrcv(msgrecvId, (void *)&msgRecv, BUFSIZ, 0, 0) == -1) {
printf("send message error\n");
}
printf("[recv] nodeId = %d, recv.nodeId = %d\n", nodeId, msgRecv.nodeId);
}
void test2(int nodeId)
{
int i = 1;
for (i = 1; i <= 3; i++) {
if (i == nodeId) {
continue;
}
int msgid = -1;
Msg_context msgSend;
msgid = msgget((key_t)i, 0666 | IPC_CREAT);
if (msgid == -1) {
printf("msgid == -1\n");
}
msgSend.nodeId = nodeId;
if (msgsnd(msgid, (void *)&msgSend, 4, 0) == -1) {
printf("send message error\n");
}
}
//com_process_send(nodeId);
sleep(1);
while (1) {
com_process_recv(nodeId);
}
}
结果如下:
I am in First process
[recv] nodeId = 2, recv.nodeId = 1
I am in second process
[recv] nodeId = 1, recv.nodeId = 2
[recv] nodeId = 3, recv.nodeId = 2
I am in Third process
[recv] nodeId = 2, recv.nodeId = 3
[recv] nodeId = 1, recv.nodeId = 3
I am in Fourth process
或者像这样:
I am in First process
[recv] nodeId = 2, recv.nodeId = 1
[recv] nodeId = 3, recv.nodeId = 3, ret = 4
I am in second process
[recv] nodeId = 1, recv.nodeId = 2
[recv] nodeId = 3, recv.nodeId = 2
I am in Third process
[recv] nodeId = 1, recv.nodeId = 3
[recv] nodeId = 2, recv.nodeId = 3
I am in Fourth process
但是,但是,如果我也将msgsnd()放入另一个函数中,它会再次正常工作。
压缩机C
typedef struct Msg_context {
int nodeId;
} Msg_context;
int com_process_send(int nodeId)
{
int i = 1;
for (i = 1; i <= 3; i++) {
if (i == nodeId) {
continue;
}
int msgid = -1;
Msg_context msgSend;
msgid = msgget((key_t)i, 0666 | IPC_CREAT);
if (msgid == -1) {
printf("msgid == -1 in %s with nodeId = %d\n", __FUNCTION__, nodeId);
}
msgSend.nodeId = nodeId;
//int length = sizeof(msgSend.nodeId);
int ret = msgsnd(msgid, (void *)&msgSend, 4, 0);
if (ret == -1) {
printf("send message error in %s with nodeId = %d\n", __FUNCTION__, nodeId);
}
printf("[send] nodeId = %d, dest msg = %d\n", nodeId, i);
}
return 0;
}
int com_process_recv(int nodeId)
{
int msgrecvId = -1;
Msg_context msgRecv;
msgrecvId = msgget((key_t)nodeId, 0666 | IPC_CREAT);
if (msgrecvId == -1) {
printf("msgrecvId == -1\n");
}
if (msgrcv(msgrecvId, (void *)&msgRecv, BUFSIZ, 0, 0) == -1) {
printf("send message error\n");
}
printf("[recv] nodeId = %d, recv.nodeId = %d\n", nodeId, msgRecv.nodeId);
}
void test2(int nodeId)
{
com_process_send(nodeId);
sleep(1);
while (1) {
com_process_recv(nodeId);
}
}
所以这很奇怪,对吧?我不明白为什么会这样。所以我非常希望你们能帮助我理解这一点。非常感谢!!!
最佳答案
根据我在您的评论中看到的内容,如果您希望将不同的进程只读消息发送给它们,那么您应该查看msgtyp
的msgrcv()
参数。
从手册页:
ssize_t msgrcv(整数msqid,void*msgp,大小msgsz,长msgtyp,
内景msgflg);
参数msgtyp指定请求的消息类型,如下所示:
如果msgtyp为0,则读取队列中的第一条消息。
如果msgtyp大于0,则读取msgtyp类型队列中的第一条消息,除非msgflg中指定了msg_except,在这种情况下,将读取msgtyp类型队列中的第一条消息。
如果msgtyp小于0,则将读取队列中最低类型小于或等于msgtyp绝对值的第一条消息。
对你来说,打电话
msgrcv(msgrecvId, (void *)&msgRecv, BUFSIZ, 0, nodeId) == -1)
将帮助您从第一个消息队列读取第一个进程,从第二个msq读取第二个进程,等等…