1. 程式人生 > >黑馬《linux系統程式設計》學習筆記(從31到35)

黑馬《linux系統程式設計》學習筆記(從31到35)

三十一. 複習檔案描述符重定向

在下面的圖中,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

三十五. 管道的讀寫行為