Hey;

I am trying to handle the SIGCHLD and therefore prevent zombie processes walking around .)

The program does not work the way it should however. I am counting how many times the ZombieHandler is called and at the end of the program it says zero. What might be causing the error?

#include <iostream>
#include <cstring>


#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
#include <wait.h>

sig_atomic_t total = 0; // number of calls to ZombieHandler

void ZombieHandler(int signal_num) // wait for the child process and clean up
{
    int status;
    wait(&status);
    total++;
}

int main(int argc, char** args)
{
    struct sigaction sa;
    memset(&sa, 0, sizeof sa);
    sa.sa_handler = &ZombieHandler;
    sigaction(SIGCHLD, &sa, NULL);  // set sa as sigaction when SIGCHLD signal occurs

    pid_t child;
    child = fork();
    if(child == 0) // child process
    {
        std::cout << "Child: My PID is " << getpid() << std::endl;
        std::cout << "Child: My parent PID is " << getppid() << std::endl;
        pid_t grandChild = fork();
        if(grandChild == 0) // grand child process
        {
            std::cout << "GrandChild: My PID is " << getpid() << std::endl;
            std::cout << "GrandChild: My Parent PID is " << getppid() << std::endl;

            return 0;
        }
        else
        {
            return 0;
        }
    }
    else // parent process
    {
        std::cout << "Parent: Number of calls to ZombieHandler is " << total << std::endl;
        return 0;
    }
}

Need help please. This one is important for me.

You have to wait when posting requests over a weekend. People are out doing stuff. I'll reply soon...

I usually don't use a signal handler to deal with DOC (Death Of Chile) events. Here is the code I have used in major enterprise applications that avoids leaving zombies around.

// Clear up any uncaught dead sub-processes.
        for (pid_t pid = waitpid(-1,nil,WNOHANG);
             pid != 0 && pid != -1;
             pid = waitpid(-1,nil,WNOHANG))
        {
            cerr << "zombie process detected (pid == " << dec << pid << ")." << endl;
        }

This is usually called at the top of the event loop in the application.

Thanks. Your way of handling is different than mine i think. Isn't handling signals more convenient way of handling zombie processes than checking zombie processes every application logic cycle?

It may not be so overwhelming but if you think ideally would not it waste some CPU power too?

Personally, I would prefer to do this when I want, rather than having the system interrupt my processing at random times. IMO, interrupts/signals are better used for unusual events, timer expiry, etc.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.