命名管道和匿名管道

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

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

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

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

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

#include 
  2 #include 
  3 #include 
  4 #include 
  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、匿名管道 :
管道的创建
命名管道和匿名管道_第3张图片
管道文件大小为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 
#include 
#include 
#include 
#include 

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 
#include 
#include 
#include 
#include 

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
命名管道和匿名管道唯一的区别就是在创建的打开,一旦这些工作完成后,它们有相同的意义。

你可能感兴趣的:(操作系统)