qfedu-linux-advanced-level/day4/homework/h4.c

80 lines
2.9 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
创建一个父进程和两个子进程,父进程从标准输入读取数据,并通过管道发送给第一个子进程,第一个子进程将数据转换为大写并发送给第二个子进程,第二个子进程将数据输出到标准输出。
【提示】定义两个无名管道并在父进程进行两次fork()创建子进程
*/
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
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;
}