③ 设计一个程序实现以下功能: 父进程创建两个子进程,父子进程间通过消息队列实现进程通信。父进程发送10条信息,分别为message1、messsage2……message10,子进程1从消息队列上读取奇数次消息,即message1、messsage3……message9,子进程2从消息队列上读取偶数次消息,即message2、messsage4……message10。 提示:可以使用不同的type将奇偶次消息区分。
时间: 2024-02-11 16:09:58 浏览: 103
以下是实现该功能的程序代码,使用了Linux中的进程通信机制——消息队列。
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#define MSG_SIZE 1024
struct message {
long type;
char text[MSG_SIZE];
};
int main() {
key_t key;
int msgid;
pid_t pid1, pid2;
struct message msg;
int i;
// 创建消息队列
key = ftok(".", 'a');
if ((msgid = msgget(key, IPC_CREAT | 0666)) == -1) {
perror("msgget error");
exit(1);
}
// 创建两个子进程
if ((pid1 = fork()) == 0) { // 子进程1
for (i = 1; i <= 10; i += 2) {
// 从消息队列中读取奇数次的消息
if (msgrcv(msgid, &msg, MSG_SIZE, i, 0) == -1) {
perror("msgrcv error");
exit(1);
}
printf("child process 1 received message: %s\n", msg.text);
}
exit(0);
} else if ((pid2 = fork()) == 0) { // 子进程2
for (i = 2; i <= 10; i += 2) {
// 从消息队列中读取偶数次的消息
if (msgrcv(msgid, &msg, MSG_SIZE, i, 0) == -1) {
perror("msgrcv error");
exit(1);
}
printf("child process 2 received message: %s\n", msg.text);
}
exit(0);
} else { // 父进程
// 发送10条消息
for (i = 1; i <= 10; i++) {
strcpy(msg.text, "message");
sprintf(msg.text + strlen(msg.text), "%d", i);
msg.type = i;
if (msgsnd(msgid, &msg, strlen(msg.text) + 1, 0) == -1) {
perror("msgsnd error");
exit(1);
}
printf("parent process sent message: %s\n", msg.text);
}
}
// 等待子进程结束
waitpid(pid1, NULL, 0);
waitpid(pid2, NULL, 0);
// 删除消息队列
if (msgctl(msgid, IPC_RMID, NULL) == -1) {
perror("msgctl error");
}
return 0;
}
```
程序首先创建一个消息队列,然后创建两个子进程。父进程向消息队列中发送10条消息,每条消息有一个类型,类型分别为1~10。子进程1从消息队列中读取奇数次的消息,即类型为1、3、5、7、9的消息;子进程2从消息队列中读取偶数次的消息,即类型为2、4、6、8、10的消息。每个进程读取到消息后都会打印出来。最后父进程等待两个子进程结束,并删除消息队列。
需要注意的是,在使用消息队列时,需要定义一个结构体来表示消息的内容,结构体中必须包含一个长整型成员用于表示消息的类型,这个类型可以是任何非负整数。在发送消息时,需要设置消息的类型,从而让接收进程可以区分不同的消息。在接收消息时,需要指定要接收的消息类型,这样就可以只接收指定类型的消息。
阅读全文