一、相关练习
1.使用有名管道实现,一个进程用于给另一个进程发消息,另一个进程收到消息后,展示到终端上,并且将消息保存到文件上一份
1.1> 01homework.c
#include <myhead.h>
int main(int argc, const char *argv[])
{
//创建一个有名管道
if(mkfifo("./pipe", 0664) == -1)
{
perror("mkfifo error");
return -1;
}
//定义通信容器
char buf[128] = "";
//创建父子进程
pid_t pid = fork();
if(pid < 0)
{
perror("fork error");
return -1;
}else if(pid > 0)
{
//子进程
//以读的形式打开文件
int rfd = open("./pipe", O_RDONLY);
if(rfd == -1)
{
perror("open error");
return -1;
}
//已追加形式打开要写入文件
int dfd = open("./test.txt", O_WRONLY|O_APPEND|O_CREAT, 0664);
if(dfd == -1)
{
perror("open dfd error");
return -1;
}
printf("管道文件读端打开\n");
while(1)
{
bzero(buf, sizeof(buf));
//读取数据
read(rfd, buf, sizeof(buf));
if(strcmp(buf, "quit") == 0)
{
break;
}
printf("收到消息为:%s\n", buf);
//将读取到的数据写入目标文件
write(dfd, buf, strlen(buf));
write(dfd, "\n", sizeof("\n"));
}
//关闭文件
close(rfd);
close(dfd);
//退出进程
exit(EXIT_SUCCESS);
}
//以写的形式打开管道文件
int wfd = open("./pipe", O_WRONLY);
if(wfd == -1)
{
perror("open wfd error");
return -1;
}
printf("管道文件写端打开\n");
usleep(10);
while(1)
{
usleep(10);
bzero(buf, sizeof(buf));
printf("请输入>>>");
fgets(buf, sizeof(buf), stdin);
buf[strlen(buf)-1] = 0;
//写入数据
write(wfd, buf, strlen(buf));
//终止判断
if(strcmp(buf, "quit") == 0)
{
break;
}
}
//回收进程资源
wait(NULL);
//关闭写端
close(wfd);
//删除管道文件
system("rm pipe");
return 0;
}
1.2> 程序运行效果
2.使用有名管道实现两个进程间相互通信
2.1> creat.c
#include <myhead.h>
int main(int argc, const char *argv[])
{
//创建管道文件
if(mkfifo("./pipe1", 0664) == -1)
{
perror("mkfifo pipe1 error");
return -1;
}
if(mkfifo("./pipe2", 0664) == -1)
{
perror("mkfifo pipe2 error");
}
getchar();
//删除管道文件
system("rm pipe1");
system("rm pipe2");
return 0;
}
2.2> fork_a.c
#include <myhead.h>
int main(int argc, const char *argv[])
{
//创建通信中间变量
char buf[128] = "";
//创建父子进程
pid_t pid = fork();
if(pid < 0)
{
perror("fork error");
return -1;
}else if(pid == 0)
{
//子进程
//以只读的形式打开管道文件2
int rfd = open("./pipe2", O_RDONLY);
if(rfd == -1)
{
perror("pipe2 open error");
return -1;
}
//读取管道文件2中的数据
while (1)
{
bzero(buf, sizeof(buf));
read(rfd, buf, sizeof(buf));
if(strcmp(buf, "quit") == 0)
{
//退出聊天
printf("B已经退出聊天,请输入“quit”退出聊天\n");
break;
}
printf("收到B的消息:%s\n", buf);
}
//关闭文件描述符
close(rfd);
//退出子进程
exit(EXIT_SUCCESS);
}
//以只写的形式打开管道文件1
int wfd = open("./pipe1", O_WRONLY);
if(wfd == -1)
{
perror("pipe1 open error");
return -1;
}
//向管道文件1中写入数据
while(1)
{
bzero(buf, sizeof(buf)); //清空容器
printf("向B发送消息:");
fgets(buf, sizeof(buf), stdin); //从标准输入中读取数据
putchar(10);
buf[strlen(buf)-1] = 0; //去掉换行符
write(wfd, buf, strlen(buf)); //向管道文件1中写入数据
if(strcmp(buf, "quit") == 0) //如果输入的是quit,则退出聊天
{
break;
}
}
//回收子进程
wait(NULL);
//关闭文件描述符
close(wfd);
return 0;
}
2.3> fork_b.c
#include <myhead.h>
int main(int argc, const char *argv[])
{
//创建通信中间变量
char buf[128] = "";
//创建父子进程
pid_t pid = fork();
if(pid < 0)
{
perror("fork error");
return -1;
}else if(pid == 0)
{
//子进程
//以只读的形式打开管道文件2
int rfd = open("./pipe1", O_RDONLY);
if(rfd == -1)
{
perror("pipe2 open error");
return -1;
}
//读取管道文件2中的数据
while (1)
{
bzero(buf, sizeof(buf));
read(rfd, buf, sizeof(buf));
if(strcmp(buf, "quit") == 0)
{
//退出聊天
printf("A已经退出聊天,请输入“quit”退出聊天\n");
break;
}
printf("收到A的消息:%s\n", buf);
}
//关闭文件描述符
close(rfd);
//退出子进程
exit(EXIT_SUCCESS);
}
//以只写的形式打开管道文件1
int wfd = open("./pipe2", O_WRONLY);
if(wfd == -1)
{
perror("pipe1 open error");
return -1;
}
//向管道文件1中写入数据
while(1)
{
bzero(buf, sizeof(buf)); //清空容器
printf("向A发送消息:");
fgets(buf, sizeof(buf), stdin); //从标准输入中读取数据
putchar(10);
buf[strlen(buf)-1] = 0; //去掉换行符
write(wfd, buf, strlen(buf)); //向管道文件1中写入数据
if(strcmp(buf, "quit") == 0) //如果输入的是quit,则退出聊天
{
break;
}
}
//回收子进程
wait(NULL);
//关闭文件描述符
close(wfd);
return 0;
}
2.4> 程序运行效果
二、思维导图