命名管道:
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的指针指向这个目录项的一个成员。