黑馬《linux系統程式設計》學習筆記(從31到35)
阿新 • • 發佈:2018-12-29
三十一. 複習檔案描述符重定向
在下面的圖中,dup2(fd[1],1)這裡的1號檔案描述符,跟隨老的fd[1],由於這裡1號檔案描述符,已經有指向,於是原指向關係撤銷,1重新建立指向,並指向fd[1]所在。
接下來,grep "bash"這裡是從0號檔案描述符,即STDIN_FILENO中讀取內容,本來STDIN_FILENO指向的是/dev/tty,也就是終端,換言之。如果沒有管道和重定向的話,grep "bash"將直接從終端中讀取內容
然而現在,我們通過dup2(fd[0],0)這一操作,使得0號檔案描述符,重新定向到了核心緩衝區的讀端,因此,現在的grep"bash"指讀取的內容,實際是0號檔案描述符現在所指的核心緩衝區中的讀端。
三十二. 複習有血緣關係的程序間通訊思路
下圖所示,是子程序寫,父程序讀。。。
如果說父程序讀,子程序寫,那麼我們需要再建立另一個管道,並且對於父程序,關閉寫端。對於子程序,關閉讀端。
三十三. 兄弟程序間通訊
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <string.h> #include <sys/wait.h> int main(int argc, const char* argv[]) { int fd[2]; int ret = pipe(fd); if(ret == -1) { perror("pipe error"); exit(1); } printf("fd[0] = %d\n", fd[0]); printf("fd[1] = %d\n", fd[1]); int i = 0; int num = 2; for(; i<num; ++i) { pid_t pid = fork(); if(pid == 0) { break; } } // parent recyle child pcb if(i == num) { close(fd[0]); close(fd[1]); // recyle pid_t wpid; while( (wpid = waitpid(-1, NULL, WNOHANG)) != -1 ) { if(wpid == 0) { continue; } printf("died child pid = %d\n", wpid); } } else if(i == 0) { // ps aux close(fd[0]); dup2(fd[1], STDOUT_FILENO); execlp("ps", "ps", "aux", NULL); } else if(i == 1) { // grep bash close(fd[1]); dup2(fd[0], STDIN_FILENO); execlp("grep", "grep", "bash", NULL); } printf("pipe[0]="%d\n",fd[0]); printf("pipe[1]="%d\n",fd[1]); return 0; }
三十四. 建立子程序需要判斷pid是否為0
三十五. 管道的讀寫行為