实验目的 实现一个管道通信程序 实验内容 由父进程创建一个管道,然后再创建3个子进程,并由这三个子进程用管道与父进程之间进行通信:子进程发送信息,父进程等三个子进程全部发完消息后再接收信息。通信的具体内容可根据自己的需要随意设计,要求能够实验阻塞型读写过程的各种情况,并要求实现进程间对管道的互斥访问。运行程序,观察各种情况下,进程实际读写的字节数以及进程阻塞唤醒情况。
时间: 2023-12-03 10:44:53 浏览: 96
电子科大操作系统实验课Linux通过管道实现进程间通信
5星 · 资源好评率100%
这是一个比较典型的进程间通信的实验,可以使用Linux系统提供的管道机制来实现。
以下是一个可能的实现过程:
```c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <fcntl.h>
#define MAX_BUF_SIZE 1024
int main() {
int pipe_fd[2]; // 用于存储管道的文件描述符
pid_t pid[3]; // 存储子进程的pid
char buf[MAX_BUF_SIZE]; // 用于存储读写的数据
int bytes_read, bytes_written; // 存储实际读写的字节数
// 创建管道
if (pipe(pipe_fd) == -1) {
perror("Failed to create pipe.");
exit(EXIT_FAILURE);
}
// 创建三个子进程
for (int i = 0; i < 3; i++) {
pid[i] = fork();
if (pid[i] < 0) {
perror("Failed to fork.");
exit(EXIT_FAILURE);
} else if (pid[i] == 0) { // 子进程
close(pipe_fd[0]); // 关闭管道的读端
// 向管道中写入数据
char msg[MAX_BUF_SIZE];
sprintf(msg, "Hello, I am child process %d.", i);
bytes_written = write(pipe_fd[1], msg, strlen(msg));
printf("Child process %d wrote %d bytes to pipe.\n", i, bytes_written);
close(pipe_fd[1]); // 关闭管道的写端
exit(EXIT_SUCCESS);
}
}
// 父进程
close(pipe_fd[1]); // 关闭管道的写端
// 读取子进程写入的数据
while (1) {
bytes_read = read(pipe_fd[0], buf, MAX_BUF_SIZE);
if (bytes_read == -1) {
perror("Failed to read from pipe.");
exit(EXIT_FAILURE);
} else if (bytes_read == 0) { // 管道已经被关闭
printf("All child processes have finished writing.\n");
break;
} else {
buf[bytes_read] = '\0';
printf("Parent process read %d bytes from pipe: %s\n", bytes_read, buf);
}
}
close(pipe_fd[0]); // 关闭管道的读端
// 等待子进程结束
for (int i = 0; i < 3; i++) {
waitpid(pid[i], NULL, 0);
}
return 0;
}
```
这段程序首先创建了一个管道,然后创建了三个子进程。每个子进程向管道中写入一条消息,然后退出。父进程在读取管道中的数据时,会阻塞等待所有子进程写完,然后再一次性读取管道中的所有数据。
需要注意的是,管道是一个全局的资源,在多个进程间共享。因此,在进行管道读写操作时,需要使用文件描述符来进行互斥访问,防止出现竞态条件。在本例中,父进程和子进程需要分别关闭管道的读端和写端,以确保读写操作的互斥性。
阅读全文