无名管道
通过一个管道(假象)进行传输数据,但是这个管道的传输方式是单工(半双工)的,就是这个管道允许进行发送和接受数据,不过不能同时进行。
创建无名管道
这里用到一个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
- #include
- #include
- #include
- #include
- #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 目标文件(查看复制后的结果)
执行成功