慕九州9493288 的学生作业:
一、代码
#include
#include
#include
#include
#include
#include
#include
#include
#define MSG_SIZE 64
#define MSG_TYPE_100 100
#define MSG_TYPE_200 200
#define MSG_PATHNAME "."
#define MSG_PROJ_ID 66
// 创建消息结构体
struct msgbuf
{
long mtype; /* message type, must be > 0 */
char mtext[MSG_SIZE]; /* message data */
};
int main()
{
key_t key;
int msgid;
// 1. 创建key
key = ftok(MSG_PATHNAME, MSG_PROJ_ID);
if (key == -1) {
perror("[ERROR]ftok(): ");
exit(EXIT_FAILURE);
}
// 2. 创建消息队列
msgid = msgget(key, IPC_CREAT | 0666);
if (msgid == -1) {
perror("[ERROR]msgget(): ");
exit(EXIT_FAILURE);
}
// 创建子进程 A(收100)
pid_t cpid_a = fork();
if (cpid_a == -1) { // 创建失败
perror("[ERROR]fork(): ");
exit(EXIT_FAILURE);
} else if (cpid_a == 0) { // 创建成功
struct msgbuf msg;
ssize_t ret;
while (1) {
ret = msgrcv(msgid, (void *) &msg, sizeof(msg.mtext), MSG_TYPE_100, 0);
if (ret == -1) {
perror("[ERROR]fork A: ");
exit(EXIT_FAILURE);
}
printf("[子进程A] 收到消息:%s\n", msg.mtext);
// 收到 quit 就退出
if (strcmp(msg.mtext, "quit") == 0) {
exit(EXIT_SUCCESS);
}
}
}
// 创建子进程 B(收200)
pid_t cpid_b = fork();
if (cpid_b == -1) { // 创建失败
perror("[ERROR]fork(): ");
exit(EXIT_FAILURE);
} else if (cpid_b == 0) { // 创建成功
struct msgbuf msg;
ssize_t ret;
while (1) {
ret = msgrcv(msgid, (void *) &msg, sizeof(msg.mtext), MSG_TYPE_200, 0);
if (ret == -1) {
perror("[ERROR]fork B: ");
exit(EXIT_FAILURE);
}
printf("[子进程B] 收到消息:%s\n", msg.mtext);
// 收到 quit 就退出
if (strcmp(msg.mtext, "quit") == 0) {
exit(EXIT_SUCCESS);
}
}
}
// 父进程:发送消息
char buf[MSG_SIZE];
struct msgbuf msg;
ssize_t ret;
while (1) {
fgets(buf, MSG_SIZE, stdin);
buf[strcspn(buf, "\n")] = 0; // 去掉换行符
// 输入 quit,发送退出消息
if (strcmp(buf, "quit") == 0) {
// 发给A
msg.mtype = MSG_TYPE_100;
strcpy(msg.mtext, buf);
ret = msgsnd(msgid, (void *) &msg, strlen(msg.mtext) + 1, 0);
if (ret == -1) {
perror("[ERROR]msgsnd() A: ");
exit(EXIT_FAILURE);
}
printf("[父进程] 发给A:%s\n", msg.mtext);
// 发给B
msg.mtype = MSG_TYPE_200;
strcpy(msg.mtext, buf);
ret = msgsnd(msgid, (void *) &msg, strlen(msg.mtext) + 1, 0);
if (ret == -1) {
perror("[ERROR]msgsnd() B: ");
exit(EXIT_FAILURE);
}
printf("[父进程] 发给B:%s\n", msg.mtext);
break;
}
// 正常消息:发给A(100)
msg.mtype = MSG_TYPE_100;
strcpy(msg.mtext, buf);
ret = msgsnd(msgid, (void *) &msg, strlen(msg.mtext) + 1, 0);
if (ret == -1) {
perror("[ERROR]msgsnd() A: ");
exit(EXIT_FAILURE);
}
printf("[父进程] 发给A:%s\n", msg.mtext);
// 正常消息:发给B(200)
msg.mtype = MSG_TYPE_200;
strcpy(msg.mtext, buf);
ret = msgsnd(msgid, (void *) &msg, strlen(msg.mtext) + 1, 0);
if (ret == -1) {
perror("[ERROR]msgsnd() B: ");
exit(EXIT_FAILURE);
}
printf("[父进程] 发给B:%s\n", msg.mtext);
}
// 等待子进程退出
waitpid(cpid_a, NULL, 0);
waitpid(cpid_b, NULL, 0);
// 删除消息队列
ret = msgctl(msgid, IPC_RMID, NULL);
if (ret == -1) {
perror("[ERROR]msgctl(): ");
exit(EXIT_FAILURE);
}
printf("[父进程] 删除消息队列成功\n");
return EXIT_SUCCESS;
}
二、结果
linux@DESKTOP-4M60T5C:~/homework/2026/0318$ gcc hw_fcipc.c
linux@DESKTOP-4M60T5C:~/homework/2026/0318$ ./a.out
hello world
[父进程] 发给A:hello world
[父进程] 发给B:hello world
[子进程A] 收到消息:hello world
[子进程B] 收到消息:hello world
quit
[父进程] 发给A:quit
[子进程A] 收到消息:quit
[父进程] 发给B:quit
[子进程B] 收到消息:quit
[父进程] 删除消息队列成功
linux@DESKTOP-4M60T5C:~/homework/2026/0318$