检查错误
时间: 2023-09-26 21:09:13 浏览: 30
上面提供的代码有一个潜在的问题:子进程写入消息时使用的消息类型是它自己的进程 ID,而父进程从消息队列中读取消息时也使用了子进程的进程 ID,这样有可能会导致父进程读取错误的消息。
为了避免这个问题,可以将消息类型设为一个非零的常数,这样父进程就可以正确地读取子进程写入的消息了。修改后的代码如下:
```
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <unistd.h>
#define MSG_SIZE 1024
#define MSG_TYPE 1
struct msgbuf {
long mtype;
char mtext[MSG_SIZE];
};
int main()
{
key_t key;
int msgid;
pid_t pid;
struct msgbuf msg;
int ret;
// 创建键值
key = ftok(".", 'a');
if (key == -1) {
perror("ftok");
exit(1);
}
// 创建消息队列
msgid = msgget(key, IPC_CREAT | 0666);
if (msgid == -1) {
perror("msgget");
exit(1);
}
// 创建子进程
pid = fork();
if (pid == -1) {
perror("fork");
exit(1);
} else if (pid == 0) {
// 子进程向消息队列中写入数据
msg.mtype = MSG_TYPE;
strcpy(msg.mtext, "Hi, this is child process sending message!");
ret = msgsnd(msgid, &msg, strlen(msg.mtext) + 1, 0);
if (ret == -1) {
perror("msgsnd");
exit(1);
}
exit(0);
} else {
// 父进程等待子进程写入消息
wait(NULL);
// 从消息队列中读取数据
ret = msgrcv(msgid, &msg, MSG_SIZE, MSG_TYPE, 0);
if (ret == -1) {
perror("msgrcv");
exit(1);
}
// 显示读取到的数据
printf("Received message: %s\n", msg.mtext);
// 删除消息队列
ret = msgctl(msgid, IPC_RMID, NULL);
if (ret == -1) {
perror("msgctl");
exit(1);
}
}
return 0;
}
```
在这个修改后的程序中,消息类型被定义为 `MSG_TYPE`,值为 1。子进程向消息队列中写入数据时,将消息类型设为 `MSG_TYPE`;父进程从消息队列中读取数据时,也将消息类型设为 `MSG_TYPE`。这样就避免了上述问题。