Invisible
Invisible

Reputation: 45

Child process becomes Defunct after fork and exec

I am learning fork and exec and creating multiple child processes using fork and execlp and all I do in the child process is let it sleep. Basically I just want all my child to be alive. But as soon as i start my monitor.cpp which creates processes all of the child exit immediately and they do defunct!

Monitor which forks multiple children

#include <iostream>
#include <thread>
#include <chrono>
#include <string>

#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

int main(int argc, char* argv[])
{
 for(size_t i=0; i<std::stoi(argv[1]) ; ++i)
 {
  int pid = fork();
  if(pid == 0)
  {
    execlp("child", "child", std::string(std::to_string(i)).c_str(), (char *)0);
    std::cout << "child exiting " << std::endl;
    exit(1);
  }
  else if(pid > 0)
  {
   std::cout <<"child started with " << pid << std::endl;
  }
  else
  {
   std::cout << "fork failed" << std::endl;
  }
 }

 while(true)
 {
  std::this_thread::sleep_for(std::chrono::seconds(100000));
 }

 return 0;
}

Child Code

#include <iostream>
#include <thread>
#include <chrono>

int main(int argc, char* argv[])
{
  std::cout << " child started with id " << argv[1] << std::endl;

  std::cout <<"child sleeping " << argv[1] << std::endl;
  std::this_thread::sleep_for(std::chrono::seconds(1000));

  std::cout << "child exiting " << argv[1] << std::endl;
  return 0;
}

Output:

child started with 1834
child started with 1835
child exiting 
child started with 1836
child exiting 
child started with 1837
child started with 1838
child started with 1839
child exiting 
child started with 1840
child started with 1841
child exiting 
child started with 1842
child started with 1843
child exiting 
child exiting 
child exiting 
child exiting 
child exiting 
child exiting

ps -ef shows all of my child processes as Defunct even though my parent is still alive.

Can you please explain what am I missing?

Upvotes: 0

Views: 972

Answers (2)

Stian Skjelstad
Stian Skjelstad

Reputation: 2335

You need to reap the child-process as they exit. This is done using wait or waitpid calls.

Until the parent has done this, they will be visible as defunc / zombie processes. (init, process 1, is responsible for reaping all process that do not have a parent after they exit)

Upvotes: 1

Paul Evans
Paul Evans

Reputation: 27567

From the 'execlp' man page:

The exec() functions only return if an error has occurred. The return value is -1, and errno is set to indicate the error.

Since "child exiting" is being printed in two places, it's not obvious if it's exiting. You need to check it's return value and errno.

Upvotes: 2

Related Questions