80 lines
2.9 KiB
C
80 lines
2.9 KiB
C
|
/*
|
|||
|
创建一个父进程和两个子进程,父进程从标准输入读取数据,并通过管道发送给第一个子进程,第一个子进程将数据转换为大写并发送给第二个子进程,第二个子进程将数据输出到标准输出。
|
|||
|
【提示】定义两个无名管道,并在父进程进行两次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;
|
|||
|
}
|