由父进程创建一个管道,然后再创建3个子进程,并由这三个子进程用管道与父进程之间进行通信:子进程发送信息,父进程等三个子进程全部发完消息后再接收信息。通信的具体内容可根据自己的需要随意设计,要求能够实验阻塞型读写过程的各种情况,并要求实现进程间对管道的互斥访问。运行程序,观察各种情况下,进程实际读写的字节数以及进程阻塞唤醒情况。
时间: 2024-02-22 16:55:38 浏览: 59
好的,这是一个经典的进程间通信问题,需要用到管道和进程间同步机制。以下是一个简单的示例代码,具体实现可能会因为操作系统的不同而有所差异。
```c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
#include <errno.h>
#define BUF_SIZE 20 // 缓冲区大小
int main() {
int pipefd[2]; // 管道文件描述符
pid_t cpid[3]; // 子进程pid
char buf[BUF_SIZE]; // 缓冲区
int readBytes; // 读取的字节数
int status; // 子进程退出状态
// 创建管道
if (pipe(pipefd) == -1) {
perror("pipe");
exit(EXIT_FAILURE);
}
// 创建三个子进程
for (int i = 0; i < 3; i++) {
cpid[i] = fork();
if (cpid[i] == -1) {
perror("fork");
exit(EXIT_FAILURE);
} else if (cpid[i] == 0) { // 子进程
close(pipefd[0]); // 子进程关闭管道读端
char msg[BUF_SIZE];
sprintf(msg, "Hello from child %d", i);
if (write(pipefd[1], msg, strlen(msg) + 1) == -1) { // 写入消息到管道
perror("write");
exit(EXIT_FAILURE);
}
printf("Child %d sent message: %s\n", i, msg);
exit(EXIT_SUCCESS);
}
}
// 父进程
close(pipefd[1]); // 父进程关闭管道写端
for (int i = 0; i < 3; i++) {
readBytes = read(pipefd[0], buf, BUF_SIZE); // 从管道读取消息
if (readBytes == -1) {
if (errno == EINTR) { // 读取遇到中断
printf("Read interrupted by signal\n");
} else {
perror("read");
exit(EXIT_FAILURE);
}
} else if (readBytes == 0) { // 管道已关闭
printf("Read end of file\n");
break;
} else {
printf("Parent received message: %s\n", buf);
}
}
// 等待子进程退出
for (int i = 0; i < 3; i++) {
waitpid(cpid[i], &status, 0);
if (WIFEXITED(status)) {
printf("Child %d exited with status %d\n", i, WEXITSTATUS(status));
} else {
printf("Child %d exited abnormally\n", i);
}
}
exit(EXIT_SUCCESS);
}
```
这个程序创建了一个管道,然后创建了三个子进程。每个子进程向管道中写入一条消息,父进程从管道中读取所有消息。在读取时,父进程会遇到三种不同的情况:
1. 读取成功并收到消息,打印消息内容
2. 管道已关闭,退出读取循环
3. 读取时遇到中断,打印提示信息
在写入和读取时,为了保证进程间对管道的互斥访问,父进程和子进程都关闭了管道的读/写端,从而实现了管道的互斥访问。
在运行程序时,可以观察阻塞型读写过程的各种情况,比如:
1. 父进程在读取之前,子进程已经全部写入消息。此时父进程可以顺利读取所有消息。
2. 父进程在读取之前,子进程只写入了一部分消息。此时父进程会阻塞等待,直到所有消息都被写入管道。
3. 父进程在读取时,子进程还没有写入任何消息。此时父进程也会阻塞等待,直到至少有一个子进程写入了消息。
4. 父进程在读取时,子进程写入消息时遇到中断。此时父进程会收到一个中断信号,并打印提示信息。
5. ...
通过观察不同情况下的程序输出,可以更深入地理解进程间通信的实现方式和机制。
阅读全文