54

Consider this simple code:

 int myvar = 0;
 int main() {
     if (fork()>0) {
       myvar++;
     } else {
       // father do nothing
     }
 }

When child increments myvar, is the value shared with the father (like pthread)?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • I agree with Tom. You could have just output the value from both processes and seen for yourself what the output was. Though remember to sleep in the one that is not expecting an increase in myvar so that it doesn't execute before the other process would (though it won't) increment it. But yeah, just run it and see. – Loduwijk Nov 28 '10 at 20:16
  • Note the misleading comment: actually, the parent process increments the counter (unless the fork failed) and the child process does nothing except exit immediately. – Jonathan Leffler Nov 28 '10 at 23:52
  • 1
    First, you aren’t checking for failure. Second, only file descriptors are shared. – tchrist Nov 28 '10 at 23:59

4 Answers4

74

No and yes.

No, they are not shared in any way which is visible to the programmer; the processes can modify their own copies of the variables independently and they will change without any noticable effect on the other process(es) which are fork() parents, siblings or descendents.

But yes, the OS actually does share the pages initially, because fork implements copy-on-write which means that provided none of the processes modifies the pages, they are shared. This is, however, an optimisation which can be ignored.

If you wanted to have shared variables, put them in an anonymous shared mapping (see mmap()) in which case they really will get shared, with all the caveats which come with that.

MarkR
  • 62,604
  • 14
  • 116
  • 151
46

fork()ing creates an exact copy of the parent process at the time of forking. However, after the fork() is completed, the child has a completely different existence, and will not report back to the parent.

In other words, no, the parent's global variables will not be altered by changes in the child.

Kevin Lacquement
  • 5,057
  • 3
  • 25
  • 30
  • 1
    +1 Although I would argue that "completely different existence" may be misleading as some objects, such as file-handles, may be shared under different circumstances, IIRC. –  Nov 28 '10 at 23:15
  • True, each process will have its own handle to any shared resources (files, pipes, etc), as a consequence of the "exact copy". Not much different, in fact, from two separate processes opening the same file. – Kevin Lacquement Nov 28 '10 at 23:34
  • 6
    There's one crucial difference between two processes opening the same file and two processes sharing a file descriptor created before forking: the forked processes share the same open file description and offset; if one process moves the file pointer (by reading or writing or seeking), it affects the other too. This does not happen with separate opens because they have separate open file descriptions. See: open(), fork(), lseek(), etc. – Jonathan Leffler Nov 28 '10 at 23:49
  • 1
    Thanks, I didn't know that. Or, if I did know it, I forgot. It's been a long time since I've fork()ed. – Kevin Lacquement Nov 28 '10 at 23:57
21

After fork(), the entire process, including all global variables, is duplicated. The child is an exact replica of the parent, except that it has a different PID(Process Id), a different parent, and fork() returned 0. Global variables are still global within its own process. So the answer is no, global variables are not shared between processes after a call to fork().

KZcoding
  • 1,417
  • 4
  • 16
  • 26
Tharun
  • 425
  • 5
  • 13
12

No, since global variables are not shared between processes unless some IPC mechanism is implemented. The memory space will be copied. As a consequence, the global variable in both processes will have the same value immediately after fork, but if one changes it, the other won't see it changed.

Threads on the other hand do share global variables.

halfer
  • 19,824
  • 17
  • 99
  • 186
Tom
  • 43,810
  • 29
  • 138
  • 169