Linux匿名管道和命名管道模拟实现

命名管道:
Client.c
  1 #include<stdio.h>                                                               
  2 #include<sys/stat.h>
  3 #include<sys/types.h>
  4 #include<fcntl.h>
  5 #include<errno.h>
  6 #include<string.h>
  7 int main()
  8 {
  9     int fd = open("./fifo",O_WRONLY);
 10     if(fd<0)
 11     {
 12         perror("open");
 13         return 2;
 14     }
 15     
 16     while(1)
 17     {
 18         printf("please enter: ");
 19         fflush(stdout);
 20         char buf[128];
 21         ssize_t _s = read(0,buf,sizeof(buf));
 22         if(_s>0)
 23         {
 24             buf[_s] = '\0';
 25         }
 26             write(fd,buf,strlen(buf));
 27     }
 28     close(fd);
 29     return 0;
 30 }                                                                               


Server.c
  2 #include<sys/stat.h>                                                            
  3 #include<sys/types.h>
  4 #include<fcntl.h>
  5 #include<errno.h>
  6 int main()
  7 {
  8     umask(0);
  9     if(mkfifo("./fifo",0666|S_IFIFO)<0)
 10     {
 11         perror("mkfifo");
 12         return 1;
 13     }
 14     int fd = open("./fifo",O_RDONLY);
 15     if(fd<0)
 16     {
 17         perror("open");
 18         return 2;
 19     }
 20     char buf[128];
 21     while(1)
 22     {
 23         ssize_t _s = read(fd,buf,sizeof(buf)-1);
 24         if(_s>0)
 25         {
 26             buf[_s] = '\0';
 27             printf("client#:%s",buf);
 28         }
 29         else if(_s==0)
 30         {
 31             printf("client quit,I should quit!\n");                             
 32             break;
 33         }
 34         else
 35             {
 36                 perror("read");
 37             }
 38     }
 39     close(fd);
 40     return 0;
 41 }

 



 匿名管道:


  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<unistd.h>
  4 #include<string.h>
  5 int main()
  6 {
  7     int pipefd[2] = {0,0};
  8     if(pipe(pipefd)<0)
  9     {
 10         perror("pipe");
 11         return 1;
 12     }
 13     pid_t id = fork();
 14     if(id<0)
 15     {                                                                       
 16         perror("fork");
 17         return 2;
 18     }
 19     else if(id==0)
 20     {//child
 21         close(pipefd[0]);
 22         char* const msg = "hello g33\n";                                    
 23         int count = 5;
 24         while(count)
 25         {
 26             write(pipefd[1],msg,strlen(msg));
 27             count--;
 28         }
 29         close(pipefd[1]);
 30         exit(1);
 31     }
 32     else
 33     {//father
 34         close(pipefd[1]);
 35         int count = 5;
 36         char buf[128];
 37         while(count)
 38         {
 39             ssize_t _s = read(pipefd[0],buf,sizeof(buf)-1);
 40             if(_s>0)
 41             {
 42                 buf[_s] = '\0';
 43                 printf("%s",buf);
 44             }
 45             else
 46             {}
 47             count--;
 48         }
 49 
 50             close(pipefd[0]);
 51             exit(2);                                                        
 52     }
 53 }   

一个管道是个无形的存在于内存中的文件。但是需要一个文件系统地inode结构,还需要两个文件号(因为是两个端)。事实上创建管道的过程类似与创建文件。再linux中,是通过get_pipe_inode来村文件系统中获得inode号。同时通过pepe_new来分配一个内存叶面当作缓存区,这个内存页面的大小的一个限制(包括软件和硬件两个部分)从应用的角度看,表现在PIPE_BUF。 


用于管道的这个文件实际上只是作为缓存的内存叶面,只不过用了文件系统的机制来管理而已,再linux内河中,函数get_unusal_fd()便是用来分配一个打开文件号,并且让这个管道叶面和文件系统挂钩。 


从内核的角度看,管道既然用文件系统的机制,那么必然需要一个文件目录项,在linux中,是通过d_alloc()来分配目录项的,然后把inode的指针指向这个目录项的一个成员。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值