簡體   English   中英

Unix中的C:fork,waitpid和管道

[英]C in Unix: fork, waitpid and pipes

我的問題是關於如何控制與管道有關的進程執行,尤其是wait / waitpid函數的實現。

當我對下面的命令創建一個管道ls | head -3 ls | head -3 ,我執行以下操作:

  • 我創建管道,分叉創建子進程
  • 對於孩子,我為標准輸入調用dup2,執行head -3命令,關閉孩子中管道的輸出端
  • 對於父級,我為標准輸出調用dup2,執行ls命令,關閉父級中管道的輸入端

我的問題: 基於此討論 ,我確實需要等待孩子完成執行,即head -3的執行。 但是,如何/在何處實現waitpid函數,使其與close[]命令不沖突?

基於此出色的文字 ,說明如下:

如果父母希望從孩子那里接收數據,則應關閉fd1,然后孩子應關閉fd0。 如果父母希望將數據發送給孩子,則應關閉fd0,然后孩子應關閉fd1。 由於描述符是在父級和子級之間共享的,因此,我們始終應確保關閉無關的管道末端。 從技術上講,如果未顯式關閉管道不必要的末端,則EOF將永遠不會返回。

因此,子級必須在執行前等待父級完成管道。

我還看到了為管道的一個過程制作兩個叉子的示例。 就像我在《 APUE ch.8》副本中的描述一樣,這是否是避免僵屍進程的目的?

考慮以下代碼實現:

    #include <stdlib.h> 
    #include <stdio.h>
    #include <sys/wait.h>
    #include <sys/types.h>

    int main()
    {
    int pid, status;

    int fd[2];

    char *com1[2];
    char *com2[3];

    com1[0] = "ls";
    com1[1] = NULL;

    com2[0] = "head";
    com2[1] = "-3";
    com2[2] = NULL;

    pipe(fd);

    if((pid = fork()) == -1)
    {
        printf("fork error");
        exit(1);
    }

    if(pid == 0)
    {
        /* Child process closes up output side of pipe */
        dup2(fd[0], 0);
        close(fd[1]);
        execvp(com2[0], com2);
    }

    else
    {

        /* if(waitpid(0, WIFEXITED(&status), 0) != pid)
        {
            printf("wait error");
        }
        is this even needed here? */

        /* Parent process closes up input side of pipe */
        dup2(fd[1], 1);
        close(fd[0]);
        execvp(com1[0], com1);

    }

    exit(0);

}

我必須承認,我在StackExchange上瀏覽了許多類似的問題。 但是,幾乎所有這些內容都具有特定的內容。 我正在尋找的是原理的解釋和功能的組合。 感謝您的時間!

你們不能都想等孩子和高管。 所以你需要有兩個孩子。 有兩種常見的方法可以執行此操作:要么有一個父進程創建兩個直接子進程,然后可以/必須等待兩個進程; 或有一個自己創建第二個孩子的孩子,這樣父孩子只需要等待一個過程終止即可。

選項1 (繼承的管道)

pipe(pi);
pid1 = fork();
if (pid1==0) { // child1
  // make redirections
  exec("head"...);
}
pid2 = fork();
if (pid2==0) { // child2
  // make redirections
  exec("ls"...);
}
// parent process
// close unuseful pipe
waitpid(pid1...);
waitpid(pid2...);

選項2 (管道僅對相關過程可見)

pid1 = fork();
if (pid1==0) { // child
  pipe(pi);
  pid2 = fork();
  if (pid2==0) { // gran child
    // make redirections
    exec("ls"...);
  }
  // make redirections
  exec("head"...);
}
// parent process
waitpid(pid1...);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM