Linux编程基础之管道通信(二)

命名管道不同于无名管道,它适用于任意两个进程之间进行数据通信,读写过程是可控制的,这里主要涉及命名管道的一个示例,

代码文件:

fifo_write.c

 1 #include <assert.h>
2 #include <ctype.h>
3 #include <errno.h>
4 #include <limits.h>
5 #include <string.h>
6 #include <stdarg.h>
7 #include <stdlib.h>
8 #include <stdio.h>
9 #include <sys/types.h>
10 #include <sys/stat.h>
11 #include <fcntl.h>
12 #include <unistd.h>
13
14 #define FIFOSERVER "/tmp/fifo"
15
16 /***********************************************************
17 功能说明:向命名管道中不断写入信息。
18 author: [email protected]
19
20 ***********************************************************/
21 void newFIFO();
22 void writeFIFO();
23
24 int main(int argc, char * argv[])
25 {
26 newFIFO();
27 writeFIFO();
28
29
30 }
31 /**********************************************************
32
33 方法功能:创建新FIFO命名管道
34
35 **********************************************************/
36 void newFIFO()
37 {
38
39 unlink(FIFOSERVER);
40
41
42 if(mkfifo(FIFOSERVER, 0777)<0)
43 {
44 perror("mkfifo");
45 exit(-1);
46
47 }
48 printf("mkfifo ok ..\n");
49
50
51
52 }
53 /**********************************************************
54
55 方法功能:写入FIFO数据
56
57 **********************************************************/
58 void writeFIFO()
59 {
60 char *str = "hello fifo ";
61 char *path = FIFOSERVER;
62
63 int fd = open(path, O_RDWR|O_NONBLOCK); //注意 这里使用O_WRONLY时要与读进程里一致,
64 if(fd<0)
65 {
66 perror("open for write");
67
68 }
69 while(1)
70 {
71
72 int rw = write( fd, str, strlen(str));
73 if(rw<0)
74 {
75 perror("write");
76 }
77 printf("write ok --return %d\n",rw);
78 sleep(3);
79
80 }
81 close(fd);
82
83
84 }

代码文件 fifo_read.c

 1 #include <assert.h>
2 #include <ctype.h>
3 #include <errno.h>
4 #include <limits.h>
5 #include <string.h>
6 #include <stdarg.h>
7 #include <stdlib.h>
8 #include <stdio.h>
9 #include <sys/types.h>
10 #include <sys/stat.h>
11 #include <fcntl.h>
12 #define MFIFO "/tmp/fifo"
13 /***********************************************************
14 功能说明:读取命令管道的数据
15 author: [email protected]
16
17 ***********************************************************/
18
19 int main(int argc, char * argv[])
20 {
21 int fd = open(MFIFO, O_RDONLY|O_NONBLOCK);//此处若用O_NONBLOCK的话,要与写进程参数一致
22 if(fd<0)
23 {
24 perror("open for read");
25 exit(-1);
26
27 }
28 printf("fd---%d\n", fd);
29
30 char buf[512];
31 int n;
32
33 while(1)
34 {
35 memset(buf, 0, sizeof(buf));
36 n = read( fd, buf, sizeof(buf));//注意此处长度不能用strlen(buf)来获得。
37 printf("read:%s --return %d\n", buf,n);
38 sleep(1);
39
40 }
41
42
43
44 }


两个文件分别在两个Shell里运行,结果如下

Linux编程基础之管道通信(二)


另一个进程,

Linux编程基础之管道通信(二)

 

上面的结果是两个进程都是非阻塞的读写,即读和写两个过程是独立进行的,上例中,因为读写的频率不一样,造成读过程中,有时有数据有时无数据的情景。

若两个都去掉O_NONBLOCK参数的话, 便是阻塞状态的,即对于读进程,若FIFO中没有数据,则会一直阻塞直到有数据写入,对于写进程,若没有进程读出管道的内容,则一直阻塞直到被读出。运行结果分别如下:

file_write:

Linux编程基础之管道通信(二)

file_read:

Linux编程基础之管道通信(二)

由此可以看出,阻塞状态时,写一次读一次,都是匹配好了,而不像前面非阻塞状态时,读和写都是独立进行的。

注:要注意读写过程中的缓冲区大小,并要区别开sizeof和strlen两个函数的区别。

你可能感兴趣的:(linux)