How to prevent creation of zombie processes while using fork() and exec() in Linux?

12,287

Solution 1

If you want to create a "detached" process that you don't have to wait for, the best way is to fork twice so that it's a "grandchild" process. Immediately waitpid on the direct child process, which should call _exit immediately after forking again (so this waitpid does not block forward progress in the parent). The grandchild process will be orphaned so it gets inherited by the init process and you never have to deal with it again.

Alternatively you can install a signal handler for SIGCHLD with SA_NOCLDWAIT. However this is a really bad idea in general since its effects are global. It will badly break any library code you use that needs to be able to wait for child processes, including standard library functions like popen, possibly wordexp, possibly grantpt, etc.

Solution 2

You can register a signal handler mechanism to prevent the child process to get zombie,

this Link will be helpful to resolution of your problem.

Solution 3

@R: In fairness, there ARE usercases where one might fork a job, and where there is absolutely no need to react on the result of the spawned child. Any call of a wait() function may eventually block the parent if there is no answer, may it? This might crash an airplane...

Solution 4

To prevent of zombie processes you need to tell the parent to wait for the child, until the child's terminates the process.
You need to use the waitpid() function that is included in the library 'sys/wait.h'

Down here you have an example code that you can use the waitpid() function.

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


int main()
{
    pid_t child_pid;
    int status;
    int local = 0;
    /* now create new process */
    child_pid = fork();

    if (child_pid >= 0) /* fork succeeded */
    {
        if (child_pid == 0) /* fork() returns 0 for the child process */
        {
            printf("child process!\n");

            // Increment the local and global variables

            printf("child PID =  %d, parent pid = %d\n", getpid(), getppid());



         }
         else /* parent process */
         {
             printf("parent process!\n");
             printf("parent PID =  %d, child pid = %d\n", getpid(), child_pid);
             wait(&status); /* wait for child to exit, and store child's exit status */
       }

     //code ..
Share:
12,287
JatiA
Author by

JatiA

Updated on November 27, 2022

Comments

  • JatiA
    JatiA over 1 year

    Is there any way to prevent creation of zombie processes while I am using fork() and exec() to run an application in background? The parent should not wait() for the child to complete. Also I cannot use sigaction() and sigaction.sa_handler because it affects all child processes which I don't want. I want something that will reap that particular child only, or that will prevent from spawning any zombie. Please help.

    • R.. GitHub STOP HELPING ICE
      R.. GitHub STOP HELPING ICE over 9 years
      As I noted in a comment to mah on Hoenir's answer, IMO it's usually an error to start a background task for which you have no way of determining its result (output/success/failure) or when it completes, but my answer addresses how to do it anyway in case you have a legitimate use for such a construct.
  • mah
    mah over 9 years
    Simply waiting for a child to terminate often defeats the reason for forking to another process so without some addition (such as was posted in @R's answer), simply saying "call wait()" doesn't seem particularly helpful.
  • R.. GitHub STOP HELPING ICE
    R.. GitHub STOP HELPING ICE over 9 years
    @mah: In fairness, if you're forking a process to do some job, you should probably care about the result of that job, and therefore have some asynchronous method to determine that it was completed (e.g. a pipe that reads EOF in your event loop) which in turn tells you when to waitpid for the child. I think it's almost-always wrong to make a truely detached process, but my answer addressed how to do that correctly anyway in case OP really needs to.
  • Omnibyte
    Omnibyte about 5 years
    (+1) but always include a short description of the solution, just in case the link won't be available in the future.