管道(Pipe)
管道是Unix的传统IPC机制之一,特点是:
1、仅用于有亲缘关系的进程之间;
2、单向数据流,即打开一个管道,一端仅用于读,另一端仅用于写;
3、传递的是字节流;
4、对它的read总是从头部返回数据,对它的write总是从尾部添加数据;
5、对于空管道:
a. 写端打开,阻塞read将一直阻塞到管道有数据(可以是EOF);非阻塞read返回EAGAIN;
b. 写端未打开,read返回0;
c. 读端未打开,write操作产生SIGPIPE。
例子:
1、父子进程间通信。(子进程传递一个文件名给父进程,由父进程打开文件并将数据传给子进程)
pipe
1 #include "unpipc.h" 2 void do_client(int, int); 3 void do_server(int, int); 4 5 // pipe is one-way channel. 6 int main() 7 { 8 int fd1[2], fd2[2]; 9 // creating pipes 10 if (pipe(fd1) || pipe (fd2)) 11 SYS_ERR(); 12 pid_t pid; 13 if ((pid = fork()) < 0) 14 SYS_ERR(); 15 if (pid == 0) { //child 16 close(fd1[0]); 17 close(fd2[1]); 18 do_client(fd1[1], fd2[0]); 19 exit(EXIT_SUCCESS); 20 } else { 21 close(fd1[1]); 22 close(fd2[0]); 23 do_server(fd2[1], fd1[0]); 24 close(fd2[1]); // this will let the read-end get a EOF 25 /*close(fd1[0]);*/ // no-necessary 26 if (waitpid(pid, NULL,1) < 0) 27 SYS_ERR(); 28 exit(EXIT_SUCCESS); 29 } 30 } 31 // fd0 for read, fd1 for write 32 void do_client(int fd1, int fd0) 33 { 34 char buf[MAX_BUF+1] = {0}; 35 // read filename 36 if (fgets(buf, MAX_BUF, stdin) == NULL) 37 return; 38 int len = strlen(buf); 39 if (buf[len-1] == '\n') // delete newline 40 len--; 41 if (write(fd1, buf, len) < 0) 42 SYS_ERR(); 43 while ((len = read(fd0, buf, MAX_BUF)) > 0) 44 buf[len] = 0, fputs(buf, stdout); // use comma 45 if (len < 0) 46 SYS_ERR(); 47 return; 48 } 49 50 void do_server(int fd1, int fd0) 51 { 52 char buf[MAX_BUF+1] = {0}; 53 int n; 54 if ((n = read(fd0, buf, MAX_BUF)) < 0) 55 SYS_ERR(); 56 if (n == 0) 57 return ; // recv EOF 58 buf[n] = 0; // add null terminator 59 int fd = open(buf, O_RDONLY, 0); 60 if (fd < 0) { 61 snprintf(buf, MAX_BUF, "%s\n", strerror(errno)); 62 if (write(fd1, buf, strlen(buf)) < 0) 63 SYS_ERR(); 64 } else { 65 while ((n = read(fd, buf, MAX_BUF)) > 0) { 66 buf[n] = 0; 67 if (write(fd1, buf, n) < 0) 68 SYS_ERR(); 69 } 70 if (n < 0) 71 SYS_ERR(); 72 close(fd); 73 } 74 return ; 75 }
2、shell命令行的管道,如“ls | sort”,它将前一个命令的输出作为后一个命令的输入。
popen
1 #include <stdio.h> 2 #include <string.h> 3 #include <errno.h> 4 5 int main(int argc, char **argv) 6 { 7 if(2 != argc) { 8 fputs("usage< ./popen proc >\n", stderr); 9 return -1; 10 } 11 FILE *fp = popen(argv[1], "w"); 12 if (NULL == fp) { 13 fprintf(stdout, "%s\n", strerror(errno)); 14 return -1; 15 } 16 17 fputs("Hello, world.", fp); 18 fputs("This is China!\n", fp); 19 pclose(fp); 20 return 0; 21 }
pout

浙公网安备 33010602011771号