标签:width 重定向 lse http ror 标准输入 fprintf 函数 execl
两个进程通过两个管道进行双向通信称为协同进程。
co_process.c
1 #include <sys/wait.h> 2 #include <sys/types.h> 3 #include <unistd.h> 4 #include <stdio.h> 5 #include <stdlib.h> 6 7 int main(void) 8 { 9 int fda[2], fdb[2]; 10 11 /** 创建两个管道 */ 12 if((pipe(fda) < 0) || (pipe(fdb) < 0)){ 13 perror("pipe error"); 14 exit(1); 15 } 16 17 pid_t pid; 18 pid = fork(); 19 if(pid < 0){ 20 perror("fork error"); 21 } 22 else if(pid == 0){ 23 /** 子进程负责从管道 a 中读取父进程写入的累加参数 x 和 y 24 * 通过 exec 函数去调用 bin/add 程序进行累加 25 * 将累加结果写入管道 b */ 26 close(fda[1]); 27 close(fdb[0]); 28 29 /** 将标准输入重定向到管道 a 的读端 */ 30 /** add 将从管道 a 中读取累加参数 x 和 y */ 31 if(dup2(fda[0], STDIN_FILENO) != STDIN_FILENO){ 32 perror("dup2 error"); 33 } 34 if(dup2(fdb[1], STDOUT_FILENO) != STDOUT_FILENO){ 35 perror("dup2 error"); 36 } 37 38 if(execlp("bin/add", "bin/add", NULL) < 0){ 39 perror("execlp error"); 40 exit(1); 41 } 42 43 close(fda[0]); 44 close(fdb[1]); 45 } 46 else { 47 /** 从标准输入上读取累加参数 x 和 y 48 * 将 x 和 y 写入管道 a 49 * 从管道 b 中读取累加的结果并输出 */ 50 close(fda[0]); 51 close(fdb[1]); 52 int x,y; 53 printf("Please input x and y:"); 54 scanf("%d %d", &x, &y); 55 56 if(write(fda[1], &x, sizeof(int)) != sizeof(int)) { 57 perror("write error"); 58 } 59 if(write(fda[1], &y, sizeof(int)) != sizeof(int)) { 60 perror("write error"); 61 } 62 63 int result = 0; 64 if(read(fdb[0], &result, sizeof(int)) != sizeof(int)){ 65 perror("read error"); 66 } 67 else { 68 printf("add result is %d\n", result); 69 } 70 71 close(fda[1]); 72 close(fdb[0]); 73 wait(0); 74 } 75 76 return 0; 77 }
add.c
1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 #include <unistd.h> 5 6 int main(void) 7 { 8 int x, y; 9 10 if(read(STDIN_FILENO, &x, sizeof(int)) < 0) { 11 perror("read error"); 12 } 13 14 if(read(STDIN_FILENO, &y, sizeof(int)) < 0) { 15 perror("read error"); 16 } 17 18 int result = x + y; 19 20 if(write(STDOUT_FILENO, &result, sizeof(int)) != sizeof(int)){ 21 perror("write error"); 22 } 23 24 exit(0); 25 }
先编译 add.c ,再编译 co_process.c,运行结果如下:
例子1,读取写端关闭的不完整管道
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <unistd.h> 5 #include <sys/types.h> 6 #include <sys/wait.h> 7 8 /** 不完整管道:读取一个写端已经关闭的管道 */ 9 int main(void) 10 { 11 int fd[2]; 12 13 if(pipe(fd) < 0){ 14 perror("pipe error"); 15 exit(1); 16 } 17 18 pid_t pid; 19 if((pid = fork()) < 0){ 20 perror("fork error"); 21 exit(1); 22 } 23 else if(pid > 0){ 24 /** 父进程从不完整管道(写端关闭)中读取数据 */ 25 sleep(5); ///< 等子进程将管道的写端关闭 26 close(fd[1]); 27 while(1){ 28 char c; 29 if(read(fd[0], &c, 1) == 0){ 30 printf("\nwrite-end of pipe closed\n"); 31 break; 32 } 33 else { 34 printf("%c", c); 35 } 36 } 37 38 close(fd[0]); 39 wait(0); 40 } 41 else { 42 /** 子进程负责将数据写入管道 */ 43 close(fd[0]); 44 char *s = "1234"; 45 write(fd[1], s, sizeof(s)); 46 /** 写入数据后关闭管道的写端 */ 47 close(fd[1]); 48 } 49 50 return 0; 51 }
编译运行结果如下:
例子2,写一个写端被关闭的不完整管道
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <unistd.h> 5 #include <sys/types.h> 6 #include <sys/wait.h> 7 #include <errno.h> 8 9 /** 不完整管道: 写一个写端已经关闭的管道 */ 10 11 void sig_handler(int signo) 12 { 13 if(signo == SIGPIPE){ 14 printf("SIGPIPE occured\n"); 15 } 16 } 17 18 int main(void) 19 { 20 int fd[2]; 21 22 if(pipe(fd) < 0){ 23 perror("pipe error"); 24 exit(1); 25 } 26 27 pid_t pid; 28 if((pid = fork()) < 0){ 29 perror("fork error"); 30 exit(1); 31 } 32 else if(pid > 0){ 33 /** 父进程负责将数据写如到不完整管道(读端关闭)中 */ 34 sleep(5); ///< 等子进程将管道的读端关闭 35 close(fd[0]); 36 if(signal(SIGPIPE, sig_handler) == SIG_ERR){ 37 perror("signal sigpipe error"); 38 exit(1); 39 } 40 41 char *s = "1234"; 42 if(write(fd[1], s, sizeof(s)) != sizeof(s)){ 43 fprintf(stderr, "%s, %s\n", strerror(errno), 44 (errno == EPIPE) ? "EPIPE" : ", unknown"); 45 46 } 47 close(fd[1]); 48 wait(0); 49 } 50 else { 51 /** 子进程关闭管道的读端 */ 52 close(fd[0]); 53 close(fd[1]); 54 } 55 56 return 0; 57 }
编译运行:
标签:width 重定向 lse http ror 标准输入 fprintf 函数 execl
原文地址:https://www.cnblogs.com/kele-dad/p/10284818.html