4

I have a program which starts a thread (using pthreads) that will do some background task for the remainder of the program. The main program is run in a terminal and a common use-case is to close it before it exits by itself using Ctrl-C. Someone asked me to be vary of the threads I spawn to become zombies. I had not thought about this problem before and I am a novice in multi-threaded programming in general. I created what I am hoping is a small, but complete, and self-contained test program that should mimic the behavior of the real program.

In the code below, is there a risk of the spawned thread to become a zombie? Recall that the program could be killed using Ctrl-C, maybe that is a special scenario, I'm not sure about that.

Right now, the thread keeps running after the MyThread object has been deleted. This is not really a problem, because in the real program, the MyThread object is destroyed just as the program is about to exit anyway. I just want to know that the thread is never in the risk of becoming a zombie in the system after the parent is gone.

I suppose I could have a mutex-protected variable that I check in the thread func each iteration to tell me if I should exit, and I could set this variable to true in the MyThread destructor, but perhaps I don't need to do that? Sorry, got a bit long, thanks for reading and thanks in advance for any help!

#include <iostream>
#include <pthread.h>
#include <unistd.h>

class MyThread
{
public:
   MyThread() : is_running(false) {}

   void Run()
   {
      if (!is_running) {
         if (pthread_create(&thread, NULL,
                            (void * (*)(void *))RunThread,
                            NULL) == 0) {
            is_running = true;
         }
         else {
            std::cerr << "pthread_create() failed." << std::endl;
         }
      }
      else {
         std::cout << "The thread was already running." << std::endl;
      }
   }
private:
   static void * RunThread(void */*arg*/)
   {
      while (true) {
         sleep(1);
         std::cout << "Hello from RunThread" << std::endl;
      }
      return NULL;
   }

   pthread_t thread;
   bool is_running;
};

int main()
{
   MyThread *thread = new MyThread;

   thread->Run();

   std::cout << "Going to sleep for five seconds." << std::endl;
   sleep(5);
   std::cout << "No longer asleep, deleting thread object." << std::endl;

   delete thread;

   std::cout << "Hit enter to exit program." << std::endl;
   std::cin.get();

   return 0;
}
Eric Lilja
  • 3,323
  • 4
  • 18
  • 15
  • http://stackoverflow.com/questions/7285109/unix-zombies-and-daemons/7285149#7285149 – Blagovest Buyukliev Oct 03 '11 at 20:10
  • Thank you all for your help, quickly and succinctly. I hope I did my stackoverflow duties as I should. – Eric Lilja Oct 03 '11 at 20:20
  • 1
    A process does not become a zombie if its parent is gone. If the parent dies, the process is immediately inherited by init (pid 1) and will be reaped when it completes. A process only becomes a zombie if it terminates while its parent is still alive, and the parent does not reap it (via wait() or waitpid()). – William Pursell Oct 03 '11 at 20:25
  • Thanks Mr Pursell for your helpful comment! – Eric Lilja Oct 03 '11 at 20:34

2 Answers2

3

Threads don't become zombies; processes do. When you kill a process, this automatically kills all of its threads.

In a nutshell, you don't need to do anything special just because you have a second thread running.

NPE
  • 486,780
  • 108
  • 951
  • 1,012
0

Ctrl+C-ing out of a program will by default kill the whole process tree, including any child processes and threads. So no worries unless you set up a custom signal handler for SIGINT.

mpartel
  • 4,474
  • 1
  • 24
  • 31