0


I am using the following code to fork a process and signal it to stop later.

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

using namespace std;

sig_atomic_t stopFlag = 0;
void measurementSignalHandler(int sig) {
  stopFlag = 1;
}

int main(int argc, char **argv) {
  pid_t measurementPid = fork();

  switch(measurementPid) {
  case -1:
    // fork failed
    cerr << "Failed to create measurement process." << endl;
    exit(1);
  case 0:
    // child
    signal(SIGUSR1, measurementSignalHandler);
    while(stopFlag == 0) {
      sleep(1);
    }

    cout << "Done with measurements." << endl;
    return 42;
  default:
    // parent
    sleep(5);

    // I do not understand why this sleep is necessary.
    kill(measurementPid, SIGUSR1);
    cout << "Giving measurement process some time to clean up."
         << endl;
    sleep(3);

    int childExitStatus;
    waitpid(measurementPid, &childExitStatus, 1);
    if(WIFEXITED(childExitStatus)) {
      cout << "Measurement process returned "
           << WEXITSTATUS(childExitStatus)
           << "." << endl;
    }
    else if(WIFSIGNALED(childExitStatus)) {
      cout << "Measurement process was terminated by signal "
           << WTERMSIG(childExitStatus)
           << "." << endl;
    }
    else {
      cout << "Measurement process ended neither on its own "
           << "nor by signal." << endl;
    }

    return 0;
  }
}

This code prints (as expected):
Giving measurement process some time to clean up.
Done with measurements.
Measurement process returned 42.

However, if I leave out the sleep statement after the kill statement, I get instead:
Giving measurement process some time to clean up.
Measurement process was terminated by signal 80.
Done with measurements.

Why does the result depend on whether I wait for three seconds? Shouldn't waitpid wait until the child returns? This does not really matter for my application (right now), but I would like to understand how to do it right. I would like to signal the child process to stop and then wait until it has finished "properly".

Thanks for your help,
Lutz

PowerGnom
  • 37
  • 6
  • 1
    You are passing 1 to `waitpid`. I'm guessing that 1 is `WAITNOHANG` and that means it won't wait until all children have finished. – RedX Apr 18 '14 at 11:38
  • Thanks, RedX, that seems to solve it. This mistake resulted from just scanning the man page instead of carefully reading the details. – PowerGnom Apr 18 '14 at 12:02

0 Answers0