为什么我的消息传递 IPC 代码不起作用? (C)
Why wont my message passing IPC code work? (C)
我正在尝试编写一个程序来实现父进程和子进程之间的基本消息传递。我在 windows 10 的 linux 子系统上执行此操作。我以前从未使用过 C,所以过去 2 天我一直在摸索和阅读教程,但我可以似乎让它发挥作用。我最多只能创建无错误的消息队列。
这是我的代码,评论了我对我在做什么的最佳理解:
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/ipc.h>
#include <sys/msg.h>
//this is the structure of the message i'm sending to the queue
struct message
{
long messagetype;
char text[10];
};
int main()
{
key_t key = 2222;
int msqid = msgget(key, IPC_CREAT); //create a message queue with the key
pid_t parentpid = getpid();
pid_t childpid = fork(); //these are mostly unused for now
if(childpid < 0) //fork failed
{
printf("fork failed\n");
return 1;
} else if(childpid == 0) //in child process
{
struct message sndmsg; //create a message to be send to the queue
printf("input message\n");
scanf("%s", sndmsg.text); //get the messages text fro input
printf("Sending message to queue: %s\n", sndmsg.text);
sndmsg.messagetype = 1; //set message type to 1
if(msgsnd(msqid, &sndmsg, sizeof(sndmsg.text), 0) < 0 ) // no idea what the last parameter really means here. check if message send fails
{
printf("error sending message\n");
} else
{
printf("sent message with text: %s\n",sndmsg.text);
}
printf("child process\n");
} else
{
wait(NULL); //wait until child process is done
struct message rcvmsg; //create a message to recieve the test from the queue
rcvmsg.messagetype = 1; //matching the message type here
if(msgrcv(msqid, &rcvmsg, sizeof(rcvmsg.text), 1, 0) < 0) //again, no idea what the last parameter does here. Checking to see if message recieve fails.
{
printf("error recieving message\n");
} else
{
printf("recieved message text : %s\n", rcvmsg.text);
}
printf("Parent process\n");
}
return 0;
}
当我 运行 时,消息发送和接收都失败(返回值 < 0)。我完全不明白 IPC_CREATE、IPC_NOWAIT 等的含义。通常就是最后一个参数在 msgsnd 和 msgrcv 中的作用。在示例中,我看到人们使用 0660 | IPC_CREAT,没有解释 0660 是什么。任何人都可以阐明我在我的代码中做错了什么,或者一般性地为通常使用 C# 和 Java 的人解释在 C 中传递的消息,因为现在它基本上是黑魔法。到目前为止,我发现的每一个资源或教程一旦达到某个点就会让我头疼。谢谢
关于0660 | IPC_CREAT
:msgget
的msgflg
参数是一个flags的集合,就是要设置一些位。 IPC_CREAT
是这些位之一,它的存在指示内核创建消息队列。低 9 位(在本例中为 0660
)编码队列的 权限。
在此示例中,0660
是一个八进制数,编码三个三元组位:110
、110
和 000
。这些三元组中的位代表队列所有者、成员的 read、write 和 execute 权限所有者组和世界其他地区分别。在这种情况下,用户和组被允许读写队列,其余的没有任何权限。
由于您未指定任何权限(一架飞机 IPC_CREAT
,没有其他任何权限),您的发送和接收调用必然会失败并出现 Permission denied
错误。
Function not implemented
是一个完全不同的野兽。我对 windows 上的 linux 了解不多,但恐怕你现在运气不好。参见 here and here。消息队列尚未实现。
"Function not implemented"(错误代码 ENOSYS)表示您的 Linux 版本已关闭此功能。不足为奇,因为它被认为已过时。
您可以重建内核以启用该功能(如果您使用的是标准内核,可能会很痛苦)或使用不同的 IPC 机制,例如管道。
我正在尝试编写一个程序来实现父进程和子进程之间的基本消息传递。我在 windows 10 的 linux 子系统上执行此操作。我以前从未使用过 C,所以过去 2 天我一直在摸索和阅读教程,但我可以似乎让它发挥作用。我最多只能创建无错误的消息队列。 这是我的代码,评论了我对我在做什么的最佳理解:
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/ipc.h>
#include <sys/msg.h>
//this is the structure of the message i'm sending to the queue
struct message
{
long messagetype;
char text[10];
};
int main()
{
key_t key = 2222;
int msqid = msgget(key, IPC_CREAT); //create a message queue with the key
pid_t parentpid = getpid();
pid_t childpid = fork(); //these are mostly unused for now
if(childpid < 0) //fork failed
{
printf("fork failed\n");
return 1;
} else if(childpid == 0) //in child process
{
struct message sndmsg; //create a message to be send to the queue
printf("input message\n");
scanf("%s", sndmsg.text); //get the messages text fro input
printf("Sending message to queue: %s\n", sndmsg.text);
sndmsg.messagetype = 1; //set message type to 1
if(msgsnd(msqid, &sndmsg, sizeof(sndmsg.text), 0) < 0 ) // no idea what the last parameter really means here. check if message send fails
{
printf("error sending message\n");
} else
{
printf("sent message with text: %s\n",sndmsg.text);
}
printf("child process\n");
} else
{
wait(NULL); //wait until child process is done
struct message rcvmsg; //create a message to recieve the test from the queue
rcvmsg.messagetype = 1; //matching the message type here
if(msgrcv(msqid, &rcvmsg, sizeof(rcvmsg.text), 1, 0) < 0) //again, no idea what the last parameter does here. Checking to see if message recieve fails.
{
printf("error recieving message\n");
} else
{
printf("recieved message text : %s\n", rcvmsg.text);
}
printf("Parent process\n");
}
return 0;
}
当我 运行 时,消息发送和接收都失败(返回值 < 0)。我完全不明白 IPC_CREATE、IPC_NOWAIT 等的含义。通常就是最后一个参数在 msgsnd 和 msgrcv 中的作用。在示例中,我看到人们使用 0660 | IPC_CREAT,没有解释 0660 是什么。任何人都可以阐明我在我的代码中做错了什么,或者一般性地为通常使用 C# 和 Java 的人解释在 C 中传递的消息,因为现在它基本上是黑魔法。到目前为止,我发现的每一个资源或教程一旦达到某个点就会让我头疼。谢谢
关于
0660 | IPC_CREAT
:msgget
的msgflg
参数是一个flags的集合,就是要设置一些位。IPC_CREAT
是这些位之一,它的存在指示内核创建消息队列。低 9 位(在本例中为0660
)编码队列的 权限。在此示例中,
0660
是一个八进制数,编码三个三元组位:110
、110
和000
。这些三元组中的位代表队列所有者、成员的 read、write 和 execute 权限所有者组和世界其他地区分别。在这种情况下,用户和组被允许读写队列,其余的没有任何权限。由于您未指定任何权限(一架飞机
IPC_CREAT
,没有其他任何权限),您的发送和接收调用必然会失败并出现Permission denied
错误。Function not implemented
是一个完全不同的野兽。我对 windows 上的 linux 了解不多,但恐怕你现在运气不好。参见 here and here。消息队列尚未实现。
"Function not implemented"(错误代码 ENOSYS)表示您的 Linux 版本已关闭此功能。不足为奇,因为它被认为已过时。
您可以重建内核以启用该功能(如果您使用的是标准内核,可能会很痛苦)或使用不同的 IPC 机制,例如管道。