管道的简单应用
/** * 父进程写入子进程读取 */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/wait.h> int main() { int mypipe[2]; //创建管道 if(pipe(mypipe) < 0){ perror("create pipe error"); exit(1); } pid_t pid; if((pid = fork()) < 0){ perror("fork error"); exit(2); } //parent process if(pid > 0){ close(mypipe[0]); //... int start = 1, end = 10000; /* if(write(mypipe[1], &start, sizeof(start)) != sizeof(int)){ perror("write error"); exit(3); } if(write(mypipe[1], &end, sizeof(end)) != sizeof(int)){ perror("write error"); exit(3); } */ FILE *fp = fdopen(mypipe[1], "wb"); int ret = fprintf(fp, "%d,%d", start, end); printf("ret=%d\n", ret); fclose(fp); wait((void *)0); close(mypipe[1]); }else{ close(mypipe[1]); //... int start = 0, end = 0; /* if(read(mypipe[0], &start, sizeof(int)) < 0){ perror("read error"); exit(4); } if(read(mypipe[0], &end, sizeof(int)) < 0){ perror("read error"); exit(4); } */ FILE *fp = fdopen(mypipe[0], "rb"); int ret = fscanf(fp, "%d,%d", &start, &end); printf("ret=%d\n", ret); fclose(fp); fprintf(stderr, "start=%d, end=%d\n", start, end); close(mypipe[0]); } return 0; }
/** * 一个子进程读取文件,一个子进程grep */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/wait.h> char *cmd1[3] = { "/bin/cat", "/etc/passwd", NULL }; char *cmd2[4] = { "/bin/grep", "root", "--color", NULL }; int main() { int mypipe[2]; if(pipe(mypipe) < 0){ perror("pipe error"); exit(1); } int i = 0; pid_t pid; for(; i < 2; i++){ pid = fork(); if(pid < 0){ perror("fork error"); exit(1); }else if(pid > 0){ if(i == 1){ close(mypipe[0]); close(mypipe[1]); wait(0); wait(0); } }else{ if(i == 0){ /** * cat 默认将数据写入标准输出,所以可以将标准输出重定向到管道 */ close(mypipe[0]); if(dup2(mypipe[1], STDOUT_FILENO) != STDOUT_FILENO){ perror("dup2 STDOUT_FILENO error"); exit(1); } close(mypipe[1]); if(execvp(cmd1[0], cmd1)){ perror("execvp error"); exit(1); } }else{ /** * grep 默认是从标准输入读取 */ close(mypipe[1]); if(dup2(mypipe[0], STDIN_FILENO) != STDIN_FILENO){ perror("dup2 STDIN_FILENO error"); exit(1); } close(mypipe[0]); if(execvp(cmd2[0], cmd2)){ perror("execvp error"); exit(1); } } } } return 0; }
协同程序
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/wait.h> int main(){ int fda[2], fdb[2]; if(pipe(fda) < 0){ perror("pipe fda error"); exit(1); } if(pipe(fdb) < 0){ perror("pipe fdb error"); exit(1); } pid_t pid; pid = fork(); if(pid < 0){ perror("fork error"); exit(1); } if(pid > 0){ /** * 1、父进程从标准输入读取x、y * 2、将x、y写入管道a * 3、从管道b读取计算的结果 */ close(fda[0]); close(fdb[1]); int a, b, ret; fprintf(stderr, "Please input a,b:\n"); fscanf(stdin, "%d,%d", &a, &b); if(write(fda[1], &a, sizeof(int)) != sizeof(int)){ perror("write error"); exit(1); } if(write(fda[1], &b, sizeof(int)) < sizeof(int)){ perror("write error"); exit(1); } if(read(fdb[0], &ret, sizeof(int)) < 0){ perror("read error"); exit(1); } printf("ret = %d\n", ret); close(fda[1]); close(fdb[0]); wait(0); }else{ /** * 1、子进程负责从管道a中读取父进程写入的x、y * 2、通过exec调用add进行计算 * 3、将计算结果写入b */ //fda:read,fdb:写 close(fda[1]); close(fdb[0]); if(dup2(fda[0], STDIN_FILENO) != STDIN_FILENO){ perror("dup2 error"); exit(1); } if(dup2(fdb[1], STDOUT_FILENO) != STDOUT_FILENO){ perror("dup2 error"); exit(1); } char *cmd[] = { "/root/unix/wangyi/src/ipc/collaborative/add", "/root/unix/wangyi/src/ipc/collaborative/add", NULL }; if(execvp(cmd[0], cmd) < 0){ perror("execvp error"); exit(1); } close(fda[0]); close(fdb[1]); } return 0; }