0

I have question from old exam, Given a C code and m is global variable, when the program finish what the value of m,the answer is "between 7 and 19" but i don't understand why, can someone explain it to me why the answer is between 7-19 and not exactly 19.

int m = 0;

int main() {
    int i;

    fork();
    m=3;
    fork();
    for(i=0;i<4;i++)
        m++;
}
David Ranieri
  • 39,972
  • 7
  • 52
  • 94
elias rizik
  • 263
  • 2
  • 11
  • 8
    @KerrekSB Probably I need coffee, but shouldn't be `7` the value of `m` at the end of each process? – LPs Oct 18 '16 at 09:02
  • 3
    What you remember the question to be is probably not what it was, because there is no return value to main,and fork just duplicates everything in that program. So all 4 programs will finish with m=7. – Secto Kia Oct 18 '16 at 09:09
  • I was going to answer this, but [since global variables are not shared](https://stackoverflow.com/questions/4298678/after-forking-are-global-variables-shared), `m` will be `7` at the end of each clone. If we assume [we share the variable](http://stackoverflow.com/q/13274786/1270789), then the variable will be always `11`, I think, except that since one copy might read the variable simultaneously with a write, there may be unexpected behaviour. It's a pretty poor question for an exam! BTW, `fork();fork();m=3;` could give 7 to 19, assuming shared memory, etc. – Ken Y-N Oct 18 '16 at 09:11
  • 1
    I agree with @LPs and @SectoKia For a programmer you can rest assured `m` is not shared between parent and its children. So when the first `fork()` happens `m` is still `0`. Then `m` is set to `3` in both parent and the child. When you do another `fork()` in both parent and the child you'll have two more children with `m` as `3`. Finally when the `for` loop finishes you'll be left with `m` as 7 in all four processes. – zapstar Oct 18 '16 at 09:12
  • at second fork there will be 4 process and the value of m=3 let's say process-1 start the for and until the for finished so that make m=7 now process-2 comes in and start the for with m = 7 and when it finish it gonna be 11 after that process 3 will add +4 to m , m=15 and the last process will make it 19 (i know there gonna be context switching and it may not be in this order but i did that to make it simple) – elias rizik Oct 18 '16 at 09:25
  • 1
    @LPs: Yes, 7, not 4, sorry. Coffee is needed on my end. I forgot that `m` starts at 3. Deleted. – Kerrek SB Oct 18 '16 at 09:30
  • 1
    @eliasrizik: Put more simply, you can just ignore all the `fork` calls to analyze this program. The forks just mean that there will ultimately be multiple identical copies of the program, but they're all the same. The forks are a red herring. – Kerrek SB Oct 18 '16 at 09:32

1 Answers1

1

The first thing to notice, analysing this problem is that there are no blocking calls, this means that when the main process reaches the end of main the program will finish, regardless of what state the other processes are in.

Using this fact we can work out the lower limit of m: this will be when the forked processes don't change the value of m before the main process exits. In this case m will start at 3, and be added to 4 times in the loop, giving you the lower limit of m = 7.

The upper limit will happen when all processes have been spawned before any enters the loop and then each process will add 4 to m (which will have a starting value of 3). In other words, m = 3 + N*4 where N is the total number of processes spawned.

So to finally get the upper limit we need to know how many processes are spawned. The first call of fork() will turn one process into two, and the subsequent call of fork() will turn each of these processes into two, meaning that N = 4.

Using our expression for m from before then we see that the upper limit is m = 3 + 4 * 4 = 19

John Sharp
  • 801
  • 4
  • 5