Question:
Does the child process execute only the code segments that come AFTER the fork() statement of it's parent?
electric
2012-09-21 23:58:08 UTC
For your consideration, the following program is taken from the book "Operating System Principles--7th Edition,Galvin,Silberschatz,Gagne chapter 3".

#include
#include

int main()
{

pid_t pid;

/*fork a child process*/
pid=fork();

if(pid>0){/*error occurred*/
fprintf("stderr,"Fork Failed");
exit(-1);
}

else if(pid==0){/*child process*/
execlp("/bin/ls","ls",NULL);

else{/*parent process*/
/*parent will wait for the child to complete*/
wait(NULL);
printf("Child Complete");
exit(0);
}
}

PLEASE answer this.Does the child process which is created due to the fork() system call,execute ONLY those code segments that come AFTER the fork() statement in its parent process?My gut feeling says that it should be so otherwise if the child were to begin executing from the beginning of the main() function, then it will again create a child and this will lead to an infinite number of fork() creating infinite number of processes, isn't it??Or am I wrong to think that way?


While we are at it, please answer the following question which I had encountered in a sample question paper for an exam:

"If a process forks thrice, in all what is the total number of child processes that will be created as a result of it?"

I answer 7!! Please see if my reasoning is right or wrong.I feel 7 because, the original process forking thrice will create 3 child processes.The first child of the original process will get the copy of the same code and hence will create TWO child processes of its own( due to 2 fork() in it).The second child get a code segment with one fork() .Using this logic recursively,I found that the first child would case 2 more child processes while the 2nd child will create one more child process bringing the total to 7.Am I right?Please give your suggestions.THANKS.
Three answers:
Jonathan
2012-09-22 13:29:16 UTC
fork() creates a complete copy. Once complete, there are two programs ready to run. Assuming a successful fork() call [enough memory, for example], the PID of the child process is returned as the function value of fork() in the parent and 0 is returned as the function value of fork() in the child process. But it does NOT matter which of the two -- original program or copied program -- gets which. The two programs are, just prior to the return from fork(), in ALL ways identical to each other. So the ONLY way to tell them apart is to peak at what the fork() call itself returns. It will be 0 for one of them, not 0 for the other. In the rare case of a fork() call failure, no process copy is made (so there is still only one program) and -1 is returned to that program (process.)



When the two identical programs are created, each of them can do exactly the same things or do different things. If they ignore the return value, then they will do the exact same things. Usually, this is NOT desired. So most programs will use the return value and do DIFFERENT things due to that. But in every way, all of the code and data are the same upon return from the successful fork() call. So it's up to you what happens then. You write the code.



...



Let's assume you write the following code:

        fork();

        fork();

        fork();



It is obvious you are NOT using the return values here. This is usually BAD practice. But for purposes of a simple question, let's see what happens when we assume that all three fork() calls are successful.



The first call to fork() will create two processes. Both are identical. Each of these two processes now return from the 1st call and begin executing at the 2nd. Both now execute the 2nd fork() call. This causes two more copies (one each), which means a total of 4 processes now exist. These four now return from the 2nd fork() call and each of the 4 now execute the 3rd fork() call, creating four more.



At the end of the 3rd fork() call there are 8 processes, all identical, none of them knowing who is parent and who is child. They will all be identical. So you really cannot say which is parent or which is child anymore, since none of them retained the return value -- the only way to know these details. From a simple operating system point of view, there is no preferred view. They are all just processes. Unix, however, usually does keep some information in the process table itself specifying which process it decided is the parent and which is the child. This is more a matter of convenience for the operating system manager of the computer, not so much a help for anything else. Early versions of Unix, I believe, didn't keep this information. But they can and do, now. It's not a defined part of the fork() call itself, though. So an operating system could either choose to keep such information in its process table, or not, and still be compliant.



If you want to think of just one of these as the parent, then there would be 7 children in addition. But the better way to think of it is as 8 equal processes. Because that's how they'd execute.
Referentially Transparent
2012-09-22 01:07:16 UTC
I haven't used fork in a while so this might be off.



Do you see where the comment that says child process is? That is what is executed. You might have got tripped up about where calling fork copies the entire executable, which I don't think is true anymore, it has become far more efficient than that.



I think you have a } in the wrong place, the child elseif will also include that else which is supposed to be the parent waiting for the child to finish.



As to your second question, I am not sure there is enough information



Something like



main()

{

fork();

fork();

fork();

printf("hello");

}



will spawn 7 children



Sane examples might not have 2^3-1 property but I could be wrong.
2016-09-21 05:09:15 UTC
If there are n fork() calls in a row like that, all victorious, then two strategies will go back from the primary, four from the moment, and so forth. There will likely be two^n strategies getting back from the nth fork. One of those would be the common dad or mum procedure (the one who obtained zero as a go back significance from all n forks). That leaves two^n-a million little one strategies. Not all of the ones are direct youngsters of the common dad or mum, incidentally. The dad or mum has most effective n youngsters, and does no longer acquire pid's or wait() on grandchildren, or first-rate*grandchildren. So, you'll be able to diagram the strategies in a binary tree with an inner node at every fork() name and a subtree for every go back from a fork(). The "genealogical" tree, centered on dad or mum-little one relationships is exclusive, being n-ary as an alternative of binary, and form of resembles the binary tree tilted by means of forty five levels. Drawing those for n=three or four must supply you a believe for what is going on within the average case.


This content was originally posted on Y! Answers, a Q&A website that shut down in 2021.
Loading...