无名管道
通过一个管道(假象)进行传输数据,但是这个管道的传输方式是单工(半双工)的,就是这个管道允许进行发送和接受数据,不过不能同时进行。
创建无名管道
这里用到一个pipe()函数,参数fd[2]为一个数组,用来保存函数返回的两个文件描述符,将fd[0]视为管道的读端,而fd[1]视为管道的写端。这也意味着,需要通过这两个设定的文件描述符进行读写。
无名管道操作特性
(1)无名管道只能用于具有亲属关系的进程之间通信(如父子进程)
所以要用无名管道,首先需要生成有个父子进程
(2)对管道的读写可以使用I/O中read()函数、write()函数直接操作文件描述符即可
如:write(fd[1],buf,nbyte);
read(fd[0],buf,N);
(3)无名管道本质是内和空间的内存段,不能使用lseek()函数定位。
(4)一次性操作,一旦管道中存在的数据被读取,管道将会清除被读取的数据。
(5)大小固定,写满会阻塞。
fork函数
fork创建父子进程 ,父进程得到一个返回值,这个返回值为子进程的ID(一定大于零的整数),子进程同样得到一个返回值但为零。
父进程读取源文件写入管道
以及子进程读取管道,写入目标文件
if(pid>0){ //父进程
while((nbyte = read(fdr,buf,N))>0) //父进程读取文件写入管道
write(fd[1],buf,nbyte);
printf("读取成功\n");
}
if(pid==0) //子进程
{
while((nbyte = read(fd[0],buf,N))>0) //子进程从管道中读取,写入文件
write(fdw,buf,nbyte);
}
源码:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/fcntl.h>
#include<error.h>
#define N 128
#define errlog(errmsg) do{perror(errmsg);\
printf("--%s--%s--%d--\n",\
__FILE__,__FUNCTION__,__LINE__);\
return -1;}while(0)
int main(int argc,char *argv[])
{
pid_t pid;
int fdr,fdw;
ssize_t nbyte;
int fd[2];
char buf[N] = " ";
if((fdr = open(argv[1],O_RDONLY))<0)
{
errlog("open error");
}
if((fdw = open(argv[2],O_CREAT|O_WRONLY|O_TRUNC,0664))<0)
{
errlog("open error");
}
if(pipe(fd)<0) //创建管道
{
errlog("pipe error");
}
pid = fork(); //创建父子进程
if(pid<0)
{
errlog("fork error");
}
else if(pid>0){ //父进程
while((nbyte = read(fdr,buf,N))>0) //父进程读取文件写入管道
write(fd[1],buf,nbyte);
printf("读取成功\n");
}
else if(pid==0) //子进程
{
while((nbyte = read(fd[0],buf,N))>0) //子进程从管道中读取,写入文件
write(fdw,buf,nbyte);
}
return 0;
}
运行:
对.c文件编译
./编译生成.o文件 源文件 目标文件
cat 目标文件(查看复制后的结果)
执行成功