编写Linux平台下的C应用程序,完成任务:有P1,P2,P3三个进程,P1和P2负责从键盘接收字符串,均发送给P3,P3接收到字符串,根据发送方分别显示"P3 received *** from P1(或P2)" ;分别用管道通信,消息队列和共享存储三种通信方式实现
时间: 2023-08-31 17:11:15 浏览: 78
linux下C语言编程(进程通信、消息队列)
4星 · 用户满意度95%
以下是三种通信方式的实现代码:
1. 管道通信
```c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#define MAX_BUF_SIZE 1024
int main(int argc, char *argv[]) {
int fd1[2], fd2[2]; // fd1为P1写入,P2读取的管道;fd2为P2写入,P1读取的管道
char buf[MAX_BUF_SIZE];
pid_t pid1, pid2;
if (pipe(fd1) == -1 || pipe(fd2) == -1) {
perror("Create pipe error");
exit(EXIT_FAILURE);
}
pid1 = fork();
if (pid1 == -1) {
perror("Create P1 process error");
exit(EXIT_FAILURE);
} else if (pid1 == 0) {
// P1子进程
close(fd1[0]); // 关闭P1读取管道的一端
while (1) {
printf("Please input a string from P1: ");
fgets(buf, MAX_BUF_SIZE, stdin);
write(fd1[1], buf, strlen(buf)); // 写入P1写入管道的一端
}
} else {
pid2 = fork();
if (pid2 == -1) {
perror("Create P2 process error");
exit(EXIT_FAILURE);
} else if (pid2 == 0) {
// P2子进程
close(fd2[0]); // 关闭P2读取管道的一端
while (1) {
printf("Please input a string from P2: ");
fgets(buf, MAX_BUF_SIZE, stdin);
write(fd2[1], buf, strlen(buf)); // 写入P2写入管道的一端
}
} else {
// P3父进程
close(fd1[1]); // 关闭P1写入管道的一端
close(fd2[1]); // 关闭P2写入管道的一端
while (1) {
if (read(fd1[0], buf, MAX_BUF_SIZE) > 0) { // 从P1读取
printf("P3 received %s from P1\n", buf);
}
if (read(fd2[0], buf, MAX_BUF_SIZE) > 0) { // 从P2读取
printf("P3 received %s from P2\n", buf);
}
}
}
}
return 0;
}
```
2. 消息队列通信
```c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#define MAX_MSG_SIZE 1024
struct msgbuf {
long mtype;
char mtext[MAX_MSG_SIZE];
};
int main(int argc, char *argv[]) {
int msgid;
struct msgbuf msg;
pid_t pid1, pid2;
msgid = msgget(IPC_PRIVATE, 0666); // 创建消息队列
if (msgid == -1) {
perror("Create message queue error");
exit(EXIT_FAILURE);
}
pid1 = fork();
if (pid1 == -1) {
perror("Create P1 process error");
exit(EXIT_FAILURE);
} else if (pid1 == 0) {
// P1子进程
while (1) {
printf("Please input a string from P1: ");
fgets(msg.mtext, MAX_MSG_SIZE, stdin);
msg.mtype = 1;
msgsnd(msgid, &msg, strlen(msg.mtext)+1, 0); // 发送到消息队列
}
} else {
pid2 = fork();
if (pid2 == -1) {
perror("Create P2 process error");
exit(EXIT_FAILURE);
} else if (pid2 == 0) {
// P2子进程
while (1) {
printf("Please input a string from P2: ");
fgets(msg.mtext, MAX_MSG_SIZE, stdin);
msg.mtype = 2;
msgsnd(msgid, &msg, strlen(msg.mtext)+1, 0); // 发送到消息队列
}
} else {
// P3父进程
while (1) {
msgrcv(msgid, &msg, MAX_MSG_SIZE, 0, 0); // 从消息队列接收
if (msg.mtype == 1) {
printf("P3 received %s from P1\n", msg.mtext);
} else if (msg.mtype == 2) {
printf("P3 received %s from P2\n", msg.mtext);
}
}
}
}
msgctl(msgid, IPC_RMID, NULL); // 销毁消息队列
return 0;
}
```
3. 共享存储通信
```c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#define MAX_BUF_SIZE 1024
int main(int argc, char *argv[]) {
int shmid;
char *shmaddr;
pid_t pid1, pid2;
shmid = shmget(IPC_PRIVATE, MAX_BUF_SIZE, 0666); // 创建共享内存
if (shmid == -1) {
perror("Create shared memory error");
exit(EXIT_FAILURE);
}
pid1 = fork();
if (pid1 == -1) {
perror("Create P1 process error");
exit(EXIT_FAILURE);
} else if (pid1 == 0) {
// P1子进程
shmaddr = (char *)shmat(shmid, NULL, 0); // 连接共享内存
while (1) {
printf("Please input a string from P1: ");
fgets(shmaddr, MAX_BUF_SIZE, stdin);
}
} else {
pid2 = fork();
if (pid2 == -1) {
perror("Create P2 process error");
exit(EXIT_FAILURE);
} else if (pid2 == 0) {
// P2子进程
shmaddr = (char *)shmat(shmid, NULL, 0); // 连接共享内存
while (1) {
printf("Please input a string from P2: ");
fgets(shmaddr, MAX_BUF_SIZE, stdin);
}
} else {
// P3父进程
shmaddr = (char *)shmat(shmid, NULL, 0); // 连接共享内存
while (1) {
if (strlen(shmaddr) > 0) {
if (pid1 == waitpid(pid1, NULL, WNOHANG)) { // 检查P1是否终止
shmdt(shmaddr); // 分离共享内存
shmctl(shmid, IPC_RMID, NULL); // 销毁共享内存
exit(EXIT_SUCCESS);
} else if (pid2 == waitpid(pid2, NULL, WNOHANG)) { // 检查P2是否终止
shmdt(shmaddr); // 分离共享内存
shmctl(shmid, IPC_RMID, NULL); // 销毁共享内存
exit(EXIT_SUCCESS);
} else {
if (strncmp(shmaddr, "\n", 1) != 0) { // 忽略回车键
printf("P3 received %s from %s\n", shmaddr, pid1 == getpid() ? "P1" : "P2");
}
memset(shmaddr, '\0', MAX_BUF_SIZE); // 清空共享内存
}
}
}
}
}
return 0;
}
```
阅读全文