進程是一個獨立的單元,每個進程各自有不同的地址空間,任何一個進程的信息在另一個進程都是不可見的,所以兩個進程間要想交換數據就必須通過內核。
而管道(pipe)就是一種實現進程間通信的一箇中間介質。它是指用於連接一個讀進程和一個寫進程,以實現它們之間通信的一個文件。所以管道用於進程間單向通信。
管道分爲匿名管道和命名管道。
匿名管道:主要用於父子進程間的通信或者兄弟進程等有親戚關係的進程間的通信。因爲只有有親戚關係的兩個進程纔可以共享一個管道。存在於內存中。
函數:
#include <unistd.h>
int pipe(int filedes[2]);
特點:
1.是單向的,即兩個進程有且只有一個讀端和寫端,不可以同時既是讀端又是寫端。
2.管道通信是面向流服務的。即它是以字符流的方式寫入的。
3.數據被進程從管道讀出後,在管道中該數據就不存在了。
4.當進程去讀空管道時,進程會阻塞。
5.當進程往滿管道里寫數據時,進程會阻塞。
6.生命週期隨進程。
7.只能用於本地,不可用於網絡。
8.不支持異步讀寫操作。
命名管道(fifo):主要用於兩個沒有親戚關係的兩個進程之間的通信。它提供了一個文件的路徑名。只要兩個進程能訪問這個路徑,就能實現通信。 存在於硬盤中
主要用到的函數:
#include <sys/types.h>
#include <sys/stat.h>
int mknod(const char *path,mode_t mod,dev_t dev);
int mkfifo(const char *path,mode_t mode);//創建一個命名管道。
特點:
1.既可以單向通信又可以實現雙向通信。
2.可以通過它的路徑被引用。
3.支持多客戶機連接。
4.既可以用於本地,也可以用於網絡。
5.支持異步重疊I/O操作。
6.既可以以流形式傳輸數據,還可以將數據集合到稱爲消息的數據塊中。
1 #include<stdio.h>
2 #include<string.h>
3 #include<stdlib.h>
4 #include<unistd.h>
5 int main()
6 {
7 int filedes[2]={0};
8 if(pipe(filedes)==-1)
9 {
10 perror("pipe");
11 exit(1);
12 }
13 pid_t pid = fork();
14 if(pid==-1)
15 {
16 perror("fork");
17 exit(1);
18 }
19 else if(pid == 0)
20 {
21 //child
22 close(filedes[0]);
23 int count = 10;
24 while(count--)
25 {
26 char buf[]="hello world";
27 ssize_t _size = write(filedes[1],buf,sizeof(buf));
28 if(_size<0)
29 {
30 perror("write");
31 exit(1);
32 }
33 sleep(1);
34 }
35 }
36 else
37 {
38 //father;
39 close(filedes[1]);
40 char buf[1024];
41 int count = 5;
42 while(1)
43 {
44 memset(buf,'\0',sizeof(buf));
45 ssize_t _size = read(filedes[0],buf,sizeof(buf));
46 if(_size<=0)
47 {
48 perror("read");
49 exit(1);
50 }
51 else
52 {
53 buf[_size]='\0';
54 printf("%s\n",buf);
55 sleep(1);
56 }
57
58 }
59
60 }
61 return 0;
62 }
client.c
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<sys/types.h>
4 #include<sys/stat.h>
5 #include<fcntl.h>
6 #include<string.h>
7 #include<unistd.h>
8 int main()
9 {
10 umask(0);
11 if(mkfifo("./.tmp",S_IFIFO | 0666)==-1)
12 {
13 perror("mkfifo");
14 exit(1);
15 }
16 int op = open("./.tmp",O_WRONLY);
17 if(op<0)
18 {
19 perror("open");
20 exit(1);
21 }
22 char buf[1024];
23 while(1)
24 {
25 memset(buf,'\0',sizeof(buf));
26 fflush(stdout);
27 printf("please say# ");
28 gets(buf);
29
31 ssize_t _size = write(op,buf,strlen(buf)+1);
32 if(_size<0)
33 {
34 perror("write");
35 exit(1);
36 }
37 }
38 return 0;
39 }
server.c
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<sys/types.h>
4 #include<sys/stat.h>
5 #include<fcntl.h>
6 #include<string.h>
7 int main()
8 {
9 int op = open("./.tmp",O_RDWR);
10 if(op<0)
11 {
12 perror("open");
13 exit(1);
14 }
15 char buf[1024];
16 while(1)
17 {
18 memset(buf,'\0',sizeof(buf));
19 fflush(stdout);
20 ssize_t _size = read(op,buf,sizeof(buf));
21 if(_size<=0)
22 {
23 printf("read end or error\n");
24 break;
25 }
26 else
27 {
28 buf[_size]='\0';
29 printf("client say# %s\n",buf);
30 }
31 }
32 return 0;
33 }
運行結果:
[fbl@localhost fifo]$ ./client
please say# nihao
please say# hello
please say# abhuuh
[fbl@localhost fifo]$ ./server
client say# nihao
client say# hello
client say# abhuuh