3

I am studying about fork(), as I learned, in fork(), the parent and child both have same "image" i.e, they both point to the same page table which all its page table entries are marked (when kernel handles the syscall) as read-only. when writing to a page, e.g, updating a variable, an anonymous page is opened, and changes are stored there, hence practically the child and parent don't have an influence on each other's variables. I encountered a strange case where I can't figure out what's going on. the thing I can't figure out is what happens when the returned fork() value ends up in the static variable and when exactly is the split made:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

static int a = 0;
static int r = 0;

int main() {
  r = fork();
  if (r > 0){
    a = 1;
  }
  if (a == 0) {
    fork();
  }
  return 0;
}

How much fork()s are executed? the first one clearly occurs, will the second one occur? when I run the code with some printing (and checking fork succeeds) it changes from one run to another although by what I learned it should be always 2 forks. Is it some problem in my computer or program I'm using to run the code or am I missing something and this changing behavior can be explained?

  • 3
    The actual forking (including copying of the parent process memory map) takes place *before* the assignment to `r` (it happens inside the `fork` function, before it returns). – Some programmer dude Feb 13 '20 at 13:32
  • 1
    This program should indeed execute `fork` 2 times, always (once in the original process, and once in the first child that is created). How exactly do you know that the behavior changes from one run to another? – zwol Feb 13 '20 at 13:36
  • 3
    Be careful with printouts. printf and company often buffer their output which can cause confusing behavior across forks; you may need to `fflush(stdout)` before forking. Also, forked processes run concurrently. If parent and child are both printing at the same time the order of printouts can vary from run to run. – John Kugelman Feb 13 '20 at 13:38
  • thanks, printf did mess up my checks! I was also not sure about the static variables, though now I see it only means they are initialized before everything else and it doesn't mean these variables are shared in some manner by the child and parent processes as i previously suspected. –  Feb 13 '20 at 14:01
  • Read [`printf()` anomaly after `fork()`](https://stackoverflow.com/a/2530870/15168). Since you don't show your instrumented code, we can't tell what is happening in it, but there are several ways for you to get confusing information. Assuming `fork()` doesn't fail, you should have two forks — the unconditional one, and the child of that first `fork()` will execute the second `fork()`. – Jonathan Leffler Feb 13 '20 at 15:51
  • @Aladin, processes like threads can produce odd behavior when you are used to sequential code. [fork()](http://man7.org/linux/man-pages/man2/fork.2.html) outlines that fork creates a new process duplicating the calling process and that the child and parent run in separate memory spaces, so you should have two different sets of statics. The trick is you after the fork you never know which process will get the first timeslice, or how long it will run. – Dweeberly Feb 13 '20 at 22:25

0 Answers0