Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. [SOLVED] child QProcess that dies with parent

[SOLVED] child QProcess that dies with parent

Scheduled Pinned Locked Moved General and Desktop
10 Posts 4 Posters 10.1k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • L Offline
    L Offline
    lisabeeren
    wrote on last edited by
    #1

    G'day,

    I'm working on a project which spawns a child process with QProcess. However, if the parent process terminates unexpectedly (program crash for example) the child process continues running. I'm wondering what the best method is for the child process to auto-terminate if the parent dies.

    At the moment I'm using a 'heart-beat' approach, where the parent process notifies the child that it is still alive by sending an interprocess message. If the child doesn't receive these notifications, then it self-terminates. This isn't fool-proof, and I occasionally get false positives, etc. and I'm expecting it to be messy tuning the timeout parameters so it works across a bunch of different machines, under different loads, etc. It's also bad stewardship of the users battery. Further, I think OSX has become a lot more aggressive at suspending programs not in active use, so the parent is deprived of processing time to perform the heartbeat.

    I was also thinking of passing the parents process ID to the child process as a command line argument, then the child could just periodically see if the parent process is still running. But I can't see a way to latch onto an existing process with QProcess.

    Anyone have any suggestions?

    many thanks

    1 Reply Last reply
    0
    • sierdzioS Offline
      sierdzioS Offline
      sierdzio
      Moderators
      wrote on last edited by
      #2

      As long as you don't use QProcess:startDetached(), the process will be terminated when the parent dies.

      (Z(:^

      1 Reply Last reply
      0
      • L Offline
        L Offline
        lisabeeren
        wrote on last edited by
        #3

        bq. As long as you don’t use QProcess:startDetached(), the process will be terminated when the parent dies.

        that's not what it does for me. i use start(), and if the process crashes the child process is not terminated. if the parent process terminates properly, then i agree, the child will be terminated, but i'm wanting to handle crashes too.

        using OSX mavericks.

        1 Reply Last reply
        0
        • sierdzioS Offline
          sierdzioS Offline
          sierdzio
          Moderators
          wrote on last edited by
          #4

          Ah sure, I've not read carefully.

          (Z(:^

          1 Reply Last reply
          0
          • S Offline
            S Offline
            serg.v.gusev
            wrote on last edited by
            #5

            Good day everyone.

            I have same issue right now. My parent process creates child one with QProcess start() method. Then they work in pair: parent sends some commands to child via stdin, child sends some data via stdout and QSharedMemory back.

            But when parent process crashes, child process keep running. I tried to implement heart-beat solution: every second parent writes 'live' to child's stdin, and child restarts it's inner timer; if no 'live' message coming for 5 seconds, child is going to exit:

            @Child::Child()
            {
            ...
            connect(dieTimer, SIGNAL(timeout()), qApp, SLOT(quit()));
            dieTimer->start(5000);
            }

            void Child::keepAlive()
            {
            dieTimer->stop();
            dieTimer->start(5000);
            }

            void Child::readCommand()
            {
            std::string line;
            std::getline(std::cin, line);

            if (line == "live")
                keepAlive();
            else if (
            ...
            

            }

            //----------------------

            Parent::Parent()
            {
            ....
            connect(keepAliveTimer, SIGNAL(timeout()), SLOT(keepAlive()));
            keepAliveTimer->start(1000);
            }

            void Parent::keepAlive()
            {
            childProcess->write("live");
            childProcess->write("\n");
            }@

            But this solution isn't working. When parent crashes, child process became init's child and keep running (or probably freeze).

            How can i handle parent's crash in Qt and quit?

            I'm working on Ubuntu 13.10 with Qt 5.2.1 (but my app should work on Ubuntu, Windows and Mac OS, so Linux-specific ways does not suitable for me).

            1 Reply Last reply
            0
            • A Offline
              A Offline
              andreyc
              wrote on last edited by
              #6

              The idea and the published part of implementation look good.
              I would use sockets instead of stdin/stdout but it is not important.

              [quote]When parent crashes, child process became init’s child and keep running (or probably freeze).[/quote]
              Have you tried to debug child process when a parent process has crashed.
              Why does it continue to reset the timer or where does it sits after the crash?

              1 Reply Last reply
              0
              • S Offline
                S Offline
                serg.v.gusev
                wrote on last edited by
                #7

                I've solved this freezes. Problem was in
                @std::getline(std::cin, line);@

                Reading from stdin is blocking operation so event loop became freezed here; i've run readCommand() method (with some fixes) in new QThread and problem has gone. Sockets is better solution, but this idea has not occurred to me. Thanks anyway.

                Nevertheless, i'm wondering why Qt doesn't provides standard interface for these seemingly simple issues. Why child processes doesn't die with their parent and why i can't set up such behaviour?

                1 Reply Last reply
                0
                • L Offline
                  L Offline
                  lisabeeren
                  wrote on last edited by
                  #8

                  hi, i tried something similar in solving this problem, but i could not get the heart-beat concept to work on OS X. however, i was using interprocess semaphores, and the issue may be specific to them.

                  the issue i had with heart-beats on OS X, is that if the program was in the background the heard-beats would stop. i think this reflects an aggressive power-saving strategy of OS X, where it suspends background processes.

                  my solution, which you may find more elegant, is as follows:

                  @
                  #ifdef WIN32
                  #include <windows.h>
                  #include <tlhelp32.h>
                  #else
                  #include "unistd.h"
                  #endif

                  bool Process::isParentRunning()
                  {
                  #ifdef WIN32

                  static unsigned long _parentPID = parentPID();
                  static void* _parentHandle = NULL;

                  if (_parentHandle == NULL && _parentPID != 0)
                  _parentHandle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, _parentPID);

                  if (_parentHandle != NULL)
                  {
                  BOOL success;
                  DWORD exitCode;

                  success = GetExitCodeProcess(_parentHandle, &exitCode);

                  return ( ! success) || exitCode == STILL_ACTIVE;
                  }
                  #else
                  return getppid() != 1;
                  #endif
                  }
                  @

                  1 Reply Last reply
                  0
                  • S Offline
                    S Offline
                    serg.v.gusev
                    wrote on last edited by
                    #9

                    Thanks! Yes, this code is more elegant.
                    But mingw says that
                    @error: 'parentPID' was not declared in this scope@

                    And i didn't found way to get parent PID under windows (although i can pass it via command line arguments). Is this code is working or just conceptual?

                    1 Reply Last reply
                    0
                    • L Offline
                      L Offline
                      lisabeeren
                      wrote on last edited by
                      #10

                      yes, this is working code from one my projects, the whole thing is:

                      process.h
                      @

                      #ifndef PROCESS_H
                      #define PROCESS_H

                      class Process
                      {
                      public:

                      static unsigned long currentPID();
                      static unsigned long parentPID();

                      static bool isParentRunning();

                      };

                      #endif // PROCESS_H
                      @

                      process.cpp
                      @

                      #include "process.h"

                      #ifdef WIN32
                      #include <windows.h>
                      #include <tlhelp32.h>
                      #else
                      #include "unistd.h"
                      #endif

                      unsigned long Process::currentPID()
                      {
                      #ifdef WIN32
                      return GetCurrentProcessId();
                      #else
                      return getpid();
                      #endif
                      }

                      unsigned long Process::parentPID()
                      {
                      #ifdef WIN32

                      HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
                      PROCESSENTRY32 pe = { 0 };
                      pe.dwSize = sizeof(PROCESSENTRY32);

                      unsigned long pid = currentPID();
                      unsigned long ppid = 0;

                      if( Process32First(h, &pe)) {
                      do {
                      if (pe.th32ProcessID == pid) {
                      ppid = pe.th32ParentProcessID;
                      break;
                      }
                      } while( Process32Next(h, &pe));
                      }

                      CloseHandle(h);

                      return ppid;

                      #else

                      return getppid();

                      #endif
                      }

                      bool Process::isParentRunning()
                      {
                      #ifdef WIN32

                      static unsigned long _parentPID = parentPID();
                      static void* _parentHandle = NULL;

                      if (_parentHandle == NULL && _parentPID != 0)
                      _parentHandle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, _parentPID);

                      if (_parentHandle != NULL)
                      {
                      BOOL success;
                      DWORD exitCode;

                      success = GetExitCodeProcess(_parentHandle, &exitCode);

                      return ( ! success) || exitCode == STILL_ACTIVE;
                      }

                      return true;

                      #else
                      return getppid() != 1;
                      #endif
                      }
                      @

                      1 Reply Last reply
                      0

                      • Login

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt Extensions
                      • Unsolved