/* 创建一个父进程和两个子进程,父进程从标准输入读取数据,并通过管道发送给第一个子进程,第一个子进程将数据转换为大写并发送给第二个子进程,第二个子进程将数据输出到标准输出。 【提示】定义两个无名管道,并在父进程进行两次fork()创建子进程 */ #include #include #include #include #include int main() { pid_t pid1, pid2; int fd1[2], fd2[2]; int f1 = pipe(fd1); int f2 = pipe(fd2); if (f1 == -1 || f2 == -1) { perror("pipe"); // 创建管道失败 _exit(1); // 创建管道失败,退出 } pid1 = fork(); if (pid1 == 0) { close(fd1[1]); // 子进程1关闭管道写端 char buf[32] = ""; int len = read(fd1[0], buf, sizeof(buf)); printf("子进程 1 收到父进程数据: %s\n", buf); for (int i = 0; i < strlen(buf); i++) { if (buf[i] >= 'a' && buf[i] <= 'z') buf[i] -= 32; } write(fd2[1], buf, strlen(buf) + 1); // 包括'\0' , 写入管道 close(fd2[1]); // 关闭管道写端 _exit(0); // 子进程1退出 } pid2 = fork(); if (pid2 == 0) { close(fd2[1]); // 子进程2关闭管道写端 char buf[32] = ""; int len = read(fd2[0], buf, sizeof(buf)); printf("子进程 2 收到子进程 1 数据: %s\n", buf); close(fd2[0]); // 关闭管道读端 _exit(0); // 子进程2退出 } close(fd1[0]); // 父进程关闭管道读端 char msg[32] = ""; printf("请在父进程中输入一段内容: "); scanf("%s", msg); write(fd1[1], msg, strlen(msg) + 1); // 包括'\0' , 写入管道 close(fd1[1]); // 关闭管道写端 /* 参数说明: 0表示等待任意子进程退出,NULL表示不关心子进程退出状态,0表示阻塞等待 返回值: 返回退出的子进程的pid,如果没有子进程退出,则返回-1 阻塞: 父进程等待子进程退出,子进程退出后,父进程才会继续执行 非阻塞: 父进程不等待子进程退出,子进程退出后,父进程也会继续执行 1 表示等待第一个子进程退出; 2 表示等待第二个子进程退出 -1 表示等待任意子进程退出 WNOHANG 表示非阻塞等待 WUNTRACED 表示如果子进程进入暂停状态,那么父进程也进入暂停状态 WCONTINUED 表示如果子进程进入继续状态,那么父进程也进入继续状态 WIFEXITED(status) 如果子进程正常退出,返回非0值 WEXITSTATUS(status) 如果WIFEXITED(status)非0值,返回子进程的退出状态 WIFSIGNALED(status) 如果子进程是因为信号而退出,返回非0值 */ waitpid(0, NULL, 0); // 等待所有子进程退出 return 0; }