gpt4 book ai didi

linux - 为什么 msgsnd() 和 msgrcv() 不能正常运行?

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:16:32 24 4
gpt4 key购买 nike

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;
}

comproc.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() 放入另一个函数时,它无法正常工作。像这样:

comproc.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() 放入另一个函数中,它会再次运行良好。

comproc.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);


}


}

所以这很奇怪,对吧?我不明白为什么会这样。所以我非常希望你们能帮助我理解这一点。非常感谢!!!

最佳答案

根据我在您的评论中读到的内容,如果您希望不同的进程只读发送给它们的消息,您应该查看 msgrcv()msgtyp 参数>

来自手册页:

ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);

The argument msgtyp specifies the type of message requested as follows:

If msgtyp is 0, then the first message in the queue is read.

If msgtyp is greater than 0, then the first message in the queue of type msgtyp is read, unless MSG_EXCEPT was specified in msgflg, in which case the first message in the queue of type not equal to msgtyp will be read.

If msgtyp is less than 0, then the first message in the queue with the lowest type less than or equal to the absolute value of msgtyp will be read.

在你的例子中,调用

    msgrcv(msgrecvId, (void *)&msgRecv, BUFSIZ, 0, nodeId) == -1)

将帮助您从第一个消息队列读取第一个进程,从第二个 msq 读取第二个进程,等等...

关于linux - 为什么 msgsnd() 和 msgrcv() 不能正常运行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50636668/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com