欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

命名管道和匿名管道

程序员文章站 2022-07-13 16:16:45
...

我们知道进程间是可以通信的。可以达到数据传输、资源共享、事件通知、进程控制等目的。进程间通信主要包括管道、系统IPC,套接字等。
管道分为三种:

  • 普通管道:一是单工,只能单向传输 ,二是仅能在父子进程或者兄弟进程中使用。
  • 流管道:去除了第一种限制,为半双工,可以双向传递,
  • 命名管道:去除了第二种限制 ,可以在很多并不相关的进程 中进行通信。

1、普通管道
int pipe(int fds[2]);//返回值0表示成功,-1表示失败
命名管道和匿名管道
fd[0]:读 fd[1]:写

子进程往管道中写数据,写数据时要关闭读端
父进程往管道中读数据,写数据时要关闭写端

命名管道和匿名管道
利用管道实现简单的操作,在管道中写入数据再读出:

#include <stdio.h>
  2 #include <unistd.h>
  3 #include <string.h>
  4 #include <stdlib.h>
  5
  6 int main(void)
  7 {
  8     int fds[2];
  9     if(pipe(fds)==-1)
10         perror("pipe"),exit(1);
11     pid_t pid=fork();
12     if(pid==-1) perror("fork"),exit(1);
13
14     if(pid==0){//子进程
15         close(fds[0]);//关闭读端
16         sleep(1);
17         write(fds[1],"abj",3);//在写端上写入abj
18         close(fds[1]);//再关闭写端
19         exit(0);
20     }else{//父进程
21         close(fds[1]);//关闭写端
22         char buf[100]={};
23         int r=read(fds[0],buf,100);//将管道中的数据读到buf中,返回值是实际读取的字节数
24         if(r==0)//读取的自己为0,代表读取文件结束
25         printf("read EOF\n");
26         else if(r==-1){
27             perror("read"),exit(1);
28         }
29         else if(r>0)
30             printf("buf=[%s]\n",buf);
31         close(fds[0]);//读取成功,关闭读端
32         exit(0);
33     }
34 }
35

命名管道和匿名管道
2、匿名管道 :
管道的创建
命名管道和匿名管道
管道文件大小为0,没有情缘关系的文件也能通过管道名,来取到该管道中的缓存。

//创建管道文件
int mkfifo(const char *name,mode_t mode)

//打开管道文件
int fd=open(name,O_RDONLY);读
int fd=open(name,O_WRONLY);写

//read/write,语义和匿名管道一样
利用命名管道实现文件的复制,代码如下:
1)、将文件写入命名管道中

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>

int main(char argc,char *argv[])
{
        mkfifo("tp",0644);//创建一个命名管道
        int infd=open("abc",O_RDONLY);//表示要复制的文件
        if(infd<0)
                perror("open"),exit(1);
        int outfd=open("tp",O_WRONLY);//写入到管道文件中
        if(outfd<0)
                perror("open"),exit(1);
        char buf[100];
        int n=0;
        while((n=read(infd,buf,100))>0){
                write(outfd,buf,n);//往outfd中写入数据
        }
        close(infd);
        close(outfd);
        return 0;
}

2)、将管道中的数据导入到拷贝文件中

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>

int main(int argc,char *argv[])
{
        int outfd=open("abc_bk",O_RDONLY|O_WRONLY|O_CREAT|O_TRUNC,0644);//需要拷贝的文件
        if(outfd<0)
                perror("open"),exit(1);
        int infd=open("tp",O_RDONLY);//打开管道,将管道中的数据读走
        if(infd<0)
                perror("open"),exit(1);
        char buf[100];
        int n;
        while((n=read(infd,buf,100))>0){
                write(outfd,buf,n);
        }
        close(infd);
        close(outfd);
        unlink("tp");//删除指定名字的文件
        return 0;
}

3、匿名管道和命名管道的区别:

匿名管道是由pipe函数创建 并打开的
命名管道是由mkfifo函数创建 的 ,打开用open
命名管道和匿名管道唯一的区别就是在创建的打开,一旦这些工作完成后,它们有相同的意义。

相关标签: 管道