管道和FIFO

pipe()函数:

#include <unistd.h>

// 返回两个文件描述符,前者(fd[0])用来读,后者(fd[1])用来写
// 成功返回0,出错返回-1
int pipe(int fd[2]);

popen()和pclose()函数:

#include <stdio.h>

// 创建一个管道,并启动另外一个进程
// 该进程要么从管道读出标准输入(type为 r),要么往管道写入标准输出(type为 w)
// 成功返回文件指针,出错返回NULL
FILE *popen(const char *command, const char *type); 
// command是一个shell命令

// 成功返回shell的终止状态,出错返回-1
int pclose(FILE *stream);

mkfifo()函数:

#include <sys/types.h>
#include <sys/stat.h>

// 创建一个FIFO(有名管道)
// 使用 open()函数打开它(pathname)来使用
// 成功返回0,出错返回-1
int mkfifo(const char *pathname, mode_t mode);

此处仅仅给出相关函数说明,有关于pipe的具体信息请自行查找。

示例1:

由子进程读取一个文件,通过管道将读取内容发送给父进程,再由父进程打印到标准输出

 1 #include <stdio.h>
 2 #include <unistd.h>
 3 #include <fcntl.h>
 4 #include <stdlib.h>
 5 #include <string.h>
 6 #include <sys/wait.h>
 7 
 8 #define MAXLINE 100
 9 
10 int main(int argc, char *argv[])
11 {    
12     if (argc != 2)
13     {
14         printf("Need two arguements!
");
15     exit(1);
16     }
17 
18     int fd[2];
19     //FILE *fp;
20     pid_t pid;
21     char readbuff[MAXLINE], writebuff[MAXLINE];
22     int n;
23     int fd_text;
24 /*
25     if ((fp = fopen(argv[1], "r")) == NULL)
26     {
27         printf("Error fopen!
");
28     exit(1);
29     }
30 */
31     if ((fd_text = open(argv[1], O_RDONLY)) == -1)
32     {
33         printf("Error open!
");
34     exit(1);
35     }
36     if (pipe(fd) == -1)
37     {
38         printf("Error pipe!
");
39     exit(1);
40     }
41     
42     if ((pid = fork()) < 0)
43     {
44         printf("Error fork!
");
45     exit(1);
46     }
47     else if (pid == 0)
48     {
49         close(fd[0]);
50     /*
51         while (fgets(writebuff, MAXLINE, fp) != NULL)
52     {
53         n = strlen(writebuff);
54         
55         if (write(fd[1], writebuff, n) != n)
56         {
57             printf("Error write!
");
58         exit(1);
59         }
60     }
61         */
62     while ((n = read(fd_text, readbuff, MAXLINE)) > 0 )
63     {
64         if (write(fd[1], readbuff, n) == -1)
65         {
66             printf("Error write!
");
67         exit(1);
68         }
69     }
70     close(fd[1]);
71         exit(0);
72     }
73     else
74     {
75         close(fd[1]);
76         
77     while (read(fd[0], readbuff, MAXLINE) > 0)
78     {
79         //write(stdout, readbuff, strlen(readbuff));
80         printf("%s
", readbuff);
81     }
82 
83     if (waitpid(pid, NULL, 0) < 0)
84     {
85         printf("Error waitpid!
");
86         exit(1);
87     }
88     
89     exit(0);
90     }
91 
92     
93     return 0;
94 }

被读取的文件内容:

[root@bogon IPC_examples]# cat text 
aaaaaaa
bbbbbbb
ccccccc

执行情况:

[root@bogon IPC_examples]# ./pipe_ep text
aaaaaaa
���
bbbbbbb
���
ccccccc
���

cccccc
���
[root@bogon IPC_examples]# vim pipe_ep
[root@bogon IPC_examples]# vim pipe_ep.c 
[root@bogon IPC_examples]# gcc pipe_ep.c -o pipe_ep
[root@bogon IPC_examples]# ./pipe_ep text
aaaaaaa
bbbbbbb
ccccccc

第一次执行时,子进程读取文本文件用的是标准I/O库的函数,然后输出出现乱码(代码中被注释掉的部分)

第二次执行时,子进程读取文本文件用的是文件I/O相关函数,输出正常

原文地址:https://www.cnblogs.com/lnlin/p/10127615.html