0

I work on code something like this

... HEADERS ...

int *var;

void child() {
  ... //some work
  free(var);
  exit(EXIT_SUCCESSFUL);
}

int main(void) {
  ...
  //allocate variable
  var = (int *) malloc(N*sizeof(int));
  ... //work with var

  for(int i; i<PROC_COUNT; i++) {
    pid_t child = fork();
    if(pid == 0) {
      child(); //main function of new proces
      break;
    }
    elseif(pid < 0) {
      //there is enormous problem -> kill every proces
      kill(0, SIGTERM);
      waitpid(0, NULL, 0); //wait for children
      free(var);
      exit(EXIT_FAILURE);
    }

  }
  free(var);
  return EXIT_SUCCESS;
}

When process is forked, all variables are cloned too. In regular case all copies of var are freed.

If there is error by fork(), I send signal SIGTERM to all created processes. And I need to write signal handler for SIGTERM which free var and terminate application. However, free() is not signal safe function -- so I shouldn`t call it. But how to free() that variable?

A lot of thanks for your answers...

EDIT: valgrind also shows still reacheable variable:

==5928== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 15 from 1)
==5928== malloc/free: in use at exit: 20 bytes in 1 blocks.
==5928== malloc/free: 1 allocs, 0 frees, 20 bytes allocated.
==5928== For counts of detected errors, rerun with: -v
==5928== searching for pointers to 1 not-freed blocks.
==5928== checked 49,164 bytes.
4

3 回答 3

4

I doubt that you need to. Any OS which supports fork(), will also automatically free allocations from malloc() when a process exits, regardless of how it does so (including termination).

There do exist environments where C programs don't run in processes, and where you have to be very careful what you leave lying around at exit. But those environments aren't POSIX, and won't support fork(). They might not support signals, for that matter. If you're writing for any such unusual environment, check your documentation...

If you want to see a clean valgrind report, then you could have the handler stick an event into the child's event loop (or set a flag and post a semaphore, or whatever), and process the event as a clean exit. That's also what you'd do if your program was an interactive application and you wanted to save the user's data on a SIGTERM, assuming your UI framework didn't already translate SIGTERM into an event for you.

于 2009-05-02T19:29:00.823 回答
0

I may be misunderstanding something, but surely after SIGTERM the whole process will disappear, taking your variable with it?

于 2009-05-02T19:27:39.533 回答
0

You could use exec to start the child process from main rather than calling the child() function directly. Use a command line argument to notify the child program to do the work in main. Then the child process will be able to cleanup properly.

于 2009-05-02T20:11:10.740 回答