3

i'd like to know if it is necessary (or advisable) to unmap shared memory (using munmap) in child created via fork, if the memory was obtained in the parent, before the fork, using mmap(..., MAP_ANONYMOUS | MAP_SHARED,...) and will also be unmapped in the parent, which will wait for the child. Also i would like to know whether it is necessary (or advisable) to close a file in the child, if the file was opened in the parent (before the fork, using fopen) and will be closed in the parent after the child terminates.

I am thinking of using a user-defined signal and a signal handler in which the parent will wait for child processes, and then the process -- wheter it is the parent or not -- will close the file and unmap the memory. This signal will be sent to all processes in the group from a process, in which an error occurred (i do not want to pass return values).

Actually it is a bit more complex, but i only want to know whether i need to do this:

void sig_handler() {
    if (getpid() == getpgrp()) // parent
        while (proc_count--)
            wait(NULL); // signal has already been sent to all child processes
    // every single process will do this:
    fclose(memory->file);
    munmap(memory, size);
    exit(123);
}

or it is completely OK to do this:

void sig_handler() {
    if (getpid() == getpgrp()) {
        while (proc_count--)
            wait(NULL);
        fclose(memory->file);
        munmap(memory, size);
    }
    exit(123);
}

I have tried closing the file in one child process; it seemed to have no effect in other processes -- i assume the fd table is copied on fork. Is there a way to make it shared between processes? (Probably not, i suspect)

Any answer is appreciated. Thank you.

PS. Is there a reason why can't i start my question with a greeting (eg. Hello) ?

  • RE your PS: See [Should 'Hi', 'thanks,' taglines, and salutations be removed from posts?](http://meta.stackexchange.com/questions/2950/should-hi-thanks-taglines-and-salutations-be-removed-from-posts) – Colonel Thirty Two Apr 25 '15 at 23:08
  • Read this: http://linux.die.net/man/7/signal Pay attention to the list of async-signal-safe functions about halfway down the page. Those are the **only** functions that are safe to call in a signal handler. – Andrew Henle Apr 25 '15 at 23:09
  • Thanks. (it says "8 more to go" so i have to write some more) –  Apr 25 '15 at 23:13

1 Answers1

0

If you're going to exit the process, there's no point in calling munmap(). The memory will be unmapped for that process when the process exits.

fclose() will flush any buffers holding unwritten data to the file. In all processes - the parent and the child. Whether or not you want that is up to you.

exit() implicitly flushes all buffers. _exit() does not flush buffers or call any other exit handlers.

Andrew Henle
  • 32,625
  • 3
  • 24
  • 56
  • So if i understand correctly i need to call neither fclose nor munmap if i call exit? Also, i use semaphores and these need to be destroyed as well, as far as i know. What could possibly happen, or what would be the worst case, if i tried to do this in in the signal handler? (Of course i would only destroy a semaphore once) Anyways, i tried to run the program through valgrind. No leaks are possible, but is there a way, or a tool similar to valgrind, to detect whether the process has explicitly called fclose prior to exiting? –  Apr 25 '15 at 23:22
  • It depends. If you `fork()` a child process, the child gets a copy of the entire address space of the parent. If the parent has unwritten data in a file buffer, so does the child. If you call `fclose()` on that file, the data in the buffer will be written to the file - and calling `exit()` does that implicitly. In both the child AND the parent process. And it depends on what kind of semaphores you are using. SysV semaphores obtained with `semget()`, POSIX semaphores (`sem_t mySem; sem_init(&mySem 0 0);`)? In general, POSIX semaphores get destroyed when the process(s) using them exit. – Andrew Henle Apr 25 '15 at 23:38
  • I am using anonymous POSIX semaphores; from `man sem_destroy`: "An unnamed semaphore should be destroyed with sem_destroy() before the memory in which it is located is deallocated. Failure to do this can result in resource leaks on some implementations." –  Apr 25 '15 at 23:43
  • Just be careful about which process(es) call `sem_destroy()` if you called `sem_init()` to initialize the semaphore as a process-shared semaphore (`sem_init(&mySem,1,0)`) and it's still in use by other processes. – Andrew Henle Apr 25 '15 at 23:49
  • The course of operation would be this: parent forks child A and B, each of them forking some more processes. In these grand-children processes, the semaphores will be waited on. If an error occurs, eg. in process B, while forking, and A has already forked its children, B will do `killpg(getpgrp(), SIGUSR1)`, and children waiting on semaphores will be interrupted and they will exit. A and B will wait for their children and the main parent will wait for A and B, then destroy the semaphores (after the waiting processes have exited). Is this OK? –  Apr 25 '15 at 23:56
  • Sounds well-thought-out. The details of the implementation will obviously matter. – Andrew Henle Apr 26 '15 at 00:03