码迷,mamicode.com
首页 > 其他好文 > 详细

IPC之PIPE

时间:2016-01-01 16:46:23      阅读:193      评论:0      收藏:0      [点我收藏+]

标签:

  管道是一种只允许用在有亲属关系的进程间通信的方式,由函数pipe创建一个管道,read,write进行读写操作。

       #include <unistd.h>

       int pipe(int pipefd[2]);

 参数pipefd[2]数组返回打开的读写描述符,pipefd[0]为读,pipefd[1]为写。

  第一个问题:文件描述符怎么会出现一个只能读,一个只能写呢?猜想是对一个文件打开了2次,一个以只读打开,一个以只写打开。使用fcntl来验证下:

       #include <unistd.h>
       #include <fcntl.h>

       int fcntl(int fd, int cmd, ... /* arg */ );
       F_GETFL (void)
              Get the file access mode and the file status flags; arg is ignored.

cmd为F_GETFL时,最后一个参数arg被忽略。测试代码:

技术分享
 1 #include <sys/types.h>
 2 #include <sys/stat.h>
 3 #include <stdio.h>
 4 #include <fcntl.h>
 5 #include <signal.h>
 6 #include <unistd.h>
 7 #include <stdlib.h>
 8 
 9 int main(void)
10 {
11     int flags;
12     int fd[2];
13 
14     if (pipe(fd) < 0)
15     {
16         perror("pipe error");
17     }
18 
19     flags = fcntl(fd[0], F_GETFL,0);
20     if ( flags < 0 )
21     {
22         perror("fcntl");
23         close(fd[0]);
24         close(fd[1]);
25     }
26     switch (flags & O_ACCMODE) 
27     {
28         case O_RDONLY:
29             printf("read only\n");
30             break;
31 
32         case O_WRONLY:
33             printf("write only\n");
34             break;
35 
36         case O_RDWR:
37             printf("read write\n");
38             break;
39 
40         default:
41             printf("unknown access mode\n");
42     }
43 
44     flags = fcntl(fd[1], F_GETFL,0);
45     if ( flags < 0 )
46     {
47         perror("fcntl");
48         close(fd[0]);
49         close(fd[1]);
50     }
51     switch (flags & O_ACCMODE) 
52     {
53         case O_RDONLY:
54             printf("read only\n");
55             break;
56 
57         case O_WRONLY:
58             printf("write only\n");
59             break;
60 
61         case O_RDWR:
62             printf("read write\n");
63             break;
64 
65         default:
66             printf("unknown access mode\n");
67     }
68     close(fd[0]);
69     close(fd[1]);
70     exit(0);
71 }
View Code

运行结果:

read only
write only

与猜想相符。

  数据的流向:

技术分享

 

从图中可以看出,进程可以以pipefd[1]写完,然后以pipefd[0]读,自己写自己读,这条数据流是通的。 验证:

技术分享
 1 #include <sys/types.h>
 2 #include <sys/stat.h>
 3 #include <stdio.h>
 4 #include <fcntl.h>
 5 #include <signal.h>
 6 #include <unistd.h>
 7 #include <stdlib.h>
 8 
 9 #define MAXLINE     4096
10 int main(void)
11 {
12     int flags;
13     int fd[2], n;
14     char buf[MAXLINE];
15     if (pipe(fd) < 0)
16     {
17         perror("pipe error");
18     }
19 
20     n = write(fd[1], "hello world\n", MAXLINE);
21     if ( n < 0 )
22     {
23         perror("write");
24         goto end;
25     }
26     n = read(fd[0],buf, n);
27     if ( n < 0 )
28     {
29         perror("read");
30         goto end;
31     }
32     printf("read:%s\n",buf);
33 
34 end:
35     close(fd[0]);
36     close(fd[1]);
37     exit(0);
38 }
View Code

输出:

read:hello world

 

  既然是进程间通信,那么管道在同一个进程中读写基本是没什么意义的,管道常用的方式是,先创建一个管道,然后fork,父子进程就共享了这个管道了。数据流向如图:

技术分享

这样,管道的写端有2个进程操作,读端有2个进程操作。但是这样一来就出现了一个问题,假设父进程读,那么这个数据是它自己写进去的呢?还是子进程写进去的?无法区分。通常一个进程关闭它的读,另一个进程关闭它的写,这样,数据流向就只有一个方向了,数据来自谁就显而易见了。如图:

技术分享

测试代码:

技术分享
 1 #include <sys/types.h>
 2 #include <sys/stat.h>
 3 #include <stdio.h>
 4 #include <fcntl.h>
 5 #include <signal.h>
 6 #include <unistd.h>
 7 #include <stdlib.h>
 8 #include <string.h>
 9 
10 #define MAXLINE     4096
11 
12 int main(void)
13 {
14     int n;
15     int fd[2];
16     pid_t pid;
17     char line[MAXLINE];
18 
19     if (pipe(fd) < 0)
20         perror("pipe error");
21     if ((pid = fork()) < 0)
22     {
23         perror("fork error");
24     }
25     else if (pid > 0)          /* parent */
26     {
27         close(fd[0]);
28         write(fd[1], "hello world\n", 12);
29     }
30     else                      /* child */
31     {
32         close(fd[1]);
33         n = read(fd[0], line, MAXLINE);
34         write(STDOUT_FILENO, line, n);
35     }
36     exit(0);
37 }
View Code

结果:

hello world

 

IPC之PIPE

标签:

原文地址:http://www.cnblogs.com/thammer/p/5093330.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!