管道(Pipe)——特殊文件
同步实现同一台机器上的两个进程之间同步传输大量数据。
int pipe(int pipefd[2]);
[0]为读,[1]为写
管道分为两种:
-
匿名管道(只能用于具有亲缘关系的进程间通信)
-
命名管道(就是磁盘上的一个特殊文件,任何知道该文件路径的进程都可以使用它进行通信)
mkfifo 管道名
上述命名创建一个以管道名而生成的命名管道文件,类型为p;
若使用cat 读取文件内容,此时,该文件则会清空;
管道只要有人读取数据,则读取到的数据在管道中直接消失,全部读完则管道清空。
子进程会自动继承父进程的所有打开的文件描述符、文件创建掩码、当前工作目录等。
三种不同的通信方式:
- 单工通信:数据传输只能沿固定的方向进行;
- 半双工通信:数据传输只能分时双向
- 全双工通信:数据传输可以同时双向传输
//匿名管道实例
#include <stdio.h>
#include <string.h>
#include <unistd.h>
int main()
{
int fd[2];
char msg[100];
if(-1 == pipe(fd))
{
perror("pipe");
return 1;
}
pid_t pid = fork();
if(pid == -1)
{
perror("fork");
return 2;
}
if(pid == 0)
{
// 子进程
read(fd[0], msg, sizeof(msg));
printf("父进程说:%s\n", msg);
strcpy(msg, "You are SB !\n");
write(fd[1], msg, strlen(msg));
close(fd[0]);
close(fd[1]);
}
else
{
int ret;
// 父进程
// sleep(1);
strcpy(msg, "你是傻子!");
write(fd[1], msg, sizeof(msg));
sleep(1);
ret = read(fd[0], msg, sizeof(msg));
if(ret >= 0) msg[ret] = '\0';
printf("子进程说:%s\n", msg);
close(fd[0]);
close(fd[1]);
}
return 0;
}
//命名管道实例
//代码1
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
int main()
{
char msg[100];
mkfifo("./dj", 0666);
int fd = open("./dj", O_RDWR);
strcpy(msg, "你是傻子!");
write(fd, msg, sizeof(msg));
sleep(1);
read(fd, msg, sizeof(msg));
printf("他说:%s\n", msg);
close(fd);
unlink("./dj");
return 0;
}
//代码2
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
int main()
{
char msg[100];
int fd = open("./dj", O_RDWR);
read(fd, msg, sizeof(msg));
printf("他说:%s\n", msg);
strcpy(msg, "You are SB !");
write(fd, msg, sizeof(msg));
close(fd);
return 0;
}