当前位置: 动力学知识库 > 问答 > 编程问答 >

c - Handle end of execution

问题描述:

I'm making a little program using a lot of forks. The first parent have to wait for everychildren.

For only one child it's easy, there is the child-end signal (SIGCLHD). But what if my first child ends before the last child? My main program runs before the end of everychilds and I need the main program wait for children.

Each child ends with an execution of another program, that explain why I can't synchronize with something like semaphores.

// Working pretty good

execvp(

c->command_name, /* program to execute */

c->argv /* argv of program to exécuter */

);

Here is my "fork-structure":

main

|

|------

| |

| |

| |------

| | |

| EOE |

| |

| EOE

|

|

EOE

Legend:

  • EOE means "End Of Execution
  • The line top-bot is the timeline
  • Each new step to the left is a new child.
  • Each vertical bar represents the execution of a bar

Thanks!

网友答案:

To find out which of the children process have terminated use waitpid in your SIGCHLD handler:

/* SIGCHLD handler. */
static void sigchld_hdl (int sig)
{
    pid_t child_pid;

    /* Wait for all dead processes.
     * We use a non-blocking call to be sure this signal handler will not
     * block if a child was cleaned up in another part of the program. */
    while ((child_pid = waitpid(-1, NULL, WNOHANG)) > 0) {
          // child_pid contains the terminated child process' pid
    }
}

For more details and a sscce this snippet was based on, check out the example's source.

EDIT:

So the question asks how to wait not only for the children, but for all descendants.

In pseudocode:

int alive_descendants = 0;

sigchld_handler() {
    decrement alive_descendants for each zombie;
}

int main() {
     setup-sigchld-handler;

     int fd[2];
     if (pipe(fd)) { error }

     to create a child:
         write a single byte to fd[1]
         fork off the child
         in the child process:
             close(fd[0]);
             to create child:
                  write a single byte to fd[1]
                  fork off the child
                  ...

     in the root process:
         close(fd[1]);
         for each byte read from fd[0], increment alive_descendants
         if alive_descendants == 0 and fd[0] is empty:
              ascertain that all descendants have terminated
              close(fd[0]);        
}
网友答案:

Did you try

// for each child spawned:
children[i] = fork(); // children is an array of pid_t
if (children[i] == 0) {
    execvp(
        c->command_name, /* programme à exécuter */
        c->argv          /* argv du programme à exécuter */
    );

// parent process keeps doing its thing, and then
for (i = 0; i < NUMBER_OF_CHILDREN; i++) {
    waitpid(children[i], NULL, 0);
}
分享给朋友:
您可能感兴趣的文章:
随机阅读: