1

This isn't in code review because I do not understand the full concept of the code to start with. If it should still be moved just let me know.

I have some code and I would like to explain my thoughts on it, and I am hoping someone can tell me where I am going wrong or getting confused at because I am still not fully sure what is occurring.

#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
int main()
   {
   pid_t pid, pid1;
   pid = fork();

   if (pid < 0) {
      fprintf (stderr, “fork() failed\n”);
      return(1);
   }
   else if (pid == 0) {
      pid1 = getpid();
      printf (“pid = %d\n”, pid); // A
      printf (“pid1 = %d\n”, pid1); // B
   }
   else {
      pid1 = getpid();
      printf (“pid = %d\n”, pid); // C
      printf (“pid1 = %d\n”, pid1); // D
      wait (NULL);
   }
   return 0;
}

From what I understand, we have two process ID's, the parent (pid) and the child (pid1). Once I call pid = fork(), I believe that the child is initiated and is given the id of 0, while the parent get's the ID of the child, let say 1337. So pid = 1337 and pid1 = 0.

So we skip the first if as no error has occurred (pid < 0), we skip the second if as well since pid does not equal 0, and then we enter the final if where C will print 1337 and D will pint out 0.

This then waits until the child is done, I think.

After that, I assume that the copied process (fork()) will then run the else if (pid == 0) but I am confused on why, because the pid is still 1337..

TLDR: If the third if should be executing first, then how do I get to the second if, but if this logic is all wrong please correct me.

KiaMorot
  • 1,668
  • 11
  • 22
Austin
  • 3,010
  • 23
  • 62
  • 97
  • Indent your code please. Always. – Jabberwocky Sep 10 '14 at 13:17
  • 1
    @MichaelWalz Just did, my bad – Austin Sep 10 '14 at 13:17
  • 1
    Read wikipage on [fork](http://en.wikipedia.org/wiki/Fork_%28system_call%29), man page [fork(2)](http://man7.org/linux/man-pages/man2/fork.2.html), and [Advanced Linux Programming](http://advancedlinuxprogramming.com/); these difficult things are explain a gazillion times! – Basile Starynkevitch Sep 10 '14 at 13:25
  • @BasileStarynkevitch I know and I understand, but something still isn't clicking, thus why I am asking here where I will generally get several views and/or explanations. – Austin Sep 10 '14 at 13:31

3 Answers3

5

A fork creates makes a (near-perfect) copy of the running process. One difference, as you surmised is the return value of fork() itself. So, assuming the fork works you have two processes executing the same code. One, the child, takes the if (pid == 0) ... path, while the parent takes the else... path. You have no information about the order in which the two processes do their work. Maybe the child goes first, maybe the parent, maybe half way through they take turns, maybe you have two processors and they run together...

Imagine you have this program written on a piece of paper and you are following along with your finger, sliding it down the page. When you get to the fork, take the paper to a copier, make a copy, put both pieces of paper on the table, put a your index finger from each hand on one of the pieces, move both your fingers, each sliding down their own sheet of paper.

John Hascall
  • 9,176
  • 6
  • 48
  • 72
  • Okay this makes sense too, would you mind looking at my comment on ralph's post and tell me what I am doing wrong still? – Austin Sep 10 '14 at 13:30
  • I believe his answer to your comment is correct. After the fork, each process has its own copy of all the variables. The values in the variables in the child process start out as whatever value they were in the parent, but they are totally separate, a change in the parent process has no effect on the child copy and vice versa. – John Hascall Sep 10 '14 at 13:35
  • Okay, I am getting there but I am still confused on something, the pid. When the child copy starts up you say that it starts at pid == 0. But if we copy at that point doesn't pid = child_ID and pid1 = 0? Or does the child process shift into the pid for its own version to give pid = 0? does that make sense? – Austin Sep 10 '14 at 13:40
  • I'm not sure I'm exactly following your question, but once `fork()` constructs the child process by making a copy of the parent process, they are totally separate after that point. This separation includes the value that `fork()` returns into each copy (the parent copy gets the pid of the child, the child copy gets 0). After the `fork()` there are two completely separate variables named ***pid***, one in each process. – John Hascall Sep 10 '14 at 13:45
  • ooooh, so they do not have the same variable assignment after the fork itself. so in the parent process the pid = child_id and in the child process the pid = 0. So what is the pid1? Maybe I am confused on what the purpose/goal of pid1..? – Austin Sep 10 '14 at 13:48
  • In each process, ***pid1*** receives the value of `getpid()`. The `getpid()` function returns a different value in each process (because they each have their own unique process id). I think showing you that is part of the point of this code snippet. – John Hascall Sep 10 '14 at 13:57
  • Oh! So I can think of pid1 as each process's "original" ID? – Austin Sep 10 '14 at 14:00
4

Everything you said is not correct

after the fork() call is executed, the child and the parent process runs in parallel, both executing the code of the program that is there after fork(). The only difference would be the pid. The child will run the same program with the pid = 0, and the parent will run the same program with the pid = (pid of child). They seperate out, both having a copy of all the variables of the program, but a different copy of the pid variable.

Haris
  • 12,120
  • 6
  • 43
  • 70
  • Okay this makes sense. So we have two programs, with parent and child one of each version. So two questions. 1. If we run this program, then is the output of A,B,C,D really coming from two difference programs? And if so (or not), would there values be: A = 0,B = child_ID,C = child_ID, and I am confused on D. – Austin Sep 10 '14 at 13:29
  • 1
    Yes the output comes from 2 different processes. A and B comes from the child process. C and D comes from the parent process. D is the pid of the parent process. B and C are equal, and is the pid of the child process you created. However you can't know which order you print A, B ,C or D in. You should prefix the output with something to identify it. – nos Sep 10 '14 at 13:32
  • 1
    @nos Okay, if I originally was told that the parent ID was 123 and the child ID was 456. then A = 0,B = 456,C = 456, D = 123? – Austin Sep 10 '14 at 13:33
  • Okay so in my head that makes sense, but when I go through the code line by line I am still slightly confused on the variable values after fork() happens. In my mind we start the program, pid = 123, pid1 = 456. We hit the fork(), then two copies are made, and what I think occurs is that both copies have the values pid = 456, and pid1 = 0. This has to be wrong because then the child copy would not run pid == 0, and printing out C and D in the parent process would give incorrect values. What am I missing during the variable assignment at fork? – Austin Sep 10 '14 at 13:44
1

pid is 0 in the child and the process ID of the child in the parent.

pid1 is set to the process ID of the current process. The value in the child's copy of pid1 is identical to the value of the parent's copy of pid.

chepner
  • 497,756
  • 71
  • 530
  • 681