父进程创建两个子进程,子进程1执行 server(),子进程2执行client();client发送10 条类型为10~1的消息入队列,server接收消 息。 要求:client将键盘输入的字符作为消息正文 发送出去,server只接收消息类型为5~1的消 息并打印输出消息正文内容及消息类型号 要求:父进程在等待子进程结束后删除消息 队列
时间: 2024-03-16 09:44:34 浏览: 50
好的,让我来回答你的问题。
这个问题涉及到进程间通信和消息队列的使用。具体的实现流程如下:
1. 父进程创建两个子进程,分别执行server()和client()函数。
2. client进程发送10条类型为10~1的消息到消息队列中,每次发送时将键盘输入的字符作为消息正文。
3. server进程从消息队列中接收消息,只接收类型为5~1的消息,并打印输出消息正文内容及消息类型号。
4. 父进程等待子进程结束后,使用msgctl()函数删除消息队列。
下面是示例代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
#define MSG_TYPE_START 10
#define MSG_TYPE_END 1
struct msgbuf {
long mtype;
char mtext[1024];
};
void client() {
int msgid;
key_t key;
struct msgbuf buf;
key = ftok(".", 'a');
msgid = msgget(key, IPC_CREAT | 0666);
if (msgid < 0) {
perror("msgget");
exit(1);
}
// 发送10条消息
for (int i = MSG_TYPE_START; i >= MSG_TYPE_END; i--) {
buf.mtype = i;
printf("请输入第%d条消息:", MSG_TYPE_START - i + 1);
fgets(buf.mtext, sizeof(buf.mtext), stdin);
buf.mtext[strlen(buf.mtext) - 1] = '\0'; // 去掉换行符
if (msgsnd(msgid, &buf, strlen(buf.mtext) + 1, IPC_NOWAIT) < 0) {
perror("msgsnd");
}
}
exit(0);
}
void server() {
int msgid;
key_t key;
struct msgbuf buf;
key = ftok(".", 'a');
msgid = msgget(key, IPC_CREAT | 0666);
if (msgid < 0) {
perror("msgget");
exit(1);
}
while (1) {
if (msgrcv(msgid, &buf, sizeof(buf.mtext), 1, IPC_NOWAIT) < 0) {
// 没有消息可读,继续等待
continue;
}
if (buf.mtype < MSG_TYPE_END || buf.mtype > MSG_TYPE_START) {
// 不是类型为1~10的消息,忽略
continue;
}
printf("收到类型为%d的消息:%s\n", buf.mtype, buf.mtext);
}
exit(0);
}
int main() {
pid_t pid1, pid2;
int status;
key_t key;
int msgid;
key = ftok(".", 'a');
msgid = msgget(key, IPC_CREAT | 0666);
if (msgid < 0) {
perror("msgget");
exit(1);
}
// 创建子进程1,执行server()
if ((pid1 = fork()) < 0) {
perror("fork");
exit(1);
} else if (pid1 == 0) {
server();
}
// 创建子进程2,执行client()
if ((pid2 = fork()) < 0) {
perror("fork");
exit(1);
} else if (pid2 == 0) {
client();
}
// 等待子进程结束
waitpid(pid1, &status, 0);
waitpid(pid2, &status, 0);
// 删除消息队列
msgctl(msgid, IPC_RMID, NULL);
return 0;
}
```
在这个示例代码中,我们使用了msgget()函数创建消息队列,使用msgsnd()函数发送消息,使用msgrcv()函数接收消息,使用msgctl()函数删除消息队列。子进程1执行server()函数,不断地从消息队列中接收消息,并判断消息类型是否符合要求;子进程2执行client()函数,发送10条消息到消息队列中,每次发送时将键盘输入的字符作为消息正文。最后,父进程等待两个子进程结束后,使用msgctl()函数删除消息队列。
希望这个回答能够帮到你!
阅读全文