Excluding the initial parent process, how many processes will be created by the following piece of code:
fork();
wait(0);
fork();
wait(0);
fork();
I was thinking of 7 processes because the father always waits for the child to end, but the child never exits. So it would be a 2**n - 1.
Every call to a fork function will create a new process. Every process (including the parent) will execute the code following its fork call. Every parent will wait for its child to die (remember that when a child calls fork, it also becomes a parent).
Draw a schema to be sure:
This gives as 7 processes, excluding the parent process.
Read the tree from its rightmost branch, and then maybe the following comments make sense:
fork(); // Process 'c0' was created
wait(0); // Parent process 'p' waits for its child 'c0' to change state.
fork(); // c1, c4
wait(0); // c0, p
fork(); // c2, c3, c5, c6
The Online Demo I created with printing statements and processes' IDs confirms that.
Reminder of the 0 argument in wait():
wait for any child process whose process group ID is equal to that of the calling process.
Read more in C - meaning of wait(NULL) when executing fork() in parallel.
Notice that the number of processes won't change if you comment out the wait calls.
Related
I'm trying to trace this program. I see that it outputs 4 times when I run it, but I don't understand why.
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
if (fork() == 0)
fork();
else
{
fork();
fork();
printf("%d\n", getpid());
}
}
To my knowledge, the if/else forks my program, then if we're in the child, it forks again. If we're in the parent, it runs the code in the else block. I get confused when I try to trace after this point, though.
Once the else statement forks again, aren't we in another child?
When do the children stop being spawned?
After getting it explained for me, I understand it now.
The first fork will spawn a child (let's call it c1):
if (fork() == 0)
The return value of fork is 0 when you're in the child. So, c1 will execute the if statement block:
fork();
The child created here, c2 (as well as c1) will both die, as they aren't going to execute the else block.
Meanwhile, the parent process will execute the else block.
fork();
This creates another child of the original parent process (c3). c3 will execute the next fork in the else block.
fork();
Now, we'll have c4, too.
Meanwhile, the original parent process will still have a fork that hasn't run. This creates the final child process, c5.
At the end of the run, there will be 4 prints: The original parent process, c3, c4, and c5.
fork in if is executed. There are two processes now child C1 and parent. Parent gets a non-zero number. Child gets 0.
Parent enters else block as it got non-zero return from fork. Now again there are two processes child C2 and parent - after executing fork in else block.
Parents fork again with C3.
Child C2 forks again with C4.
Note that C1 also forked but it will not do anything other than ending the if block. (We don't care about this).
So 4, printf execution - one by Parent, C2, C3 and C4.
The key one line Golden rule is:-
Both parent and child process start their execution right after the system call fork()
And each process ends when the control reaches the end of the function here it is main(). (Answering your last question).
What I am trying to do in my code is have a parent process that forks two children processes. This is how I've done it:
pid = fork();
if(pid != 1)
pid1 = fork();
The next thing I'm trying to do is switch between the processes continuously (from child to other child to parent, in that order) using semaphores. ie the child process will say A, the other child will say B, the parent will say C, the child will say D, and so on.
My two questions are:
Say you call sem_wait(sem) in a semaphore and the process blocks as it should. You then move on and the other process ends up calling sem_post(sem). Will the code following the sem_wait be immediately executed after the sem_post? ie does the execution "jump back" to the code after the sem_wait even if it doesn't come "next" in the program?
if(stuff){
a;
sem_wait(sem);
b;
}
c;
sem_post(sem);
Will b be executed even though it's "before" the post in terms of coming before it textually?
How can I identify the processes so that I may give one of them permission to execute? I have to confirm that a process is either child 1 , child 2 or parent before I give it permission to execute the code, but how can I tell? I tried to check using if statements (if(pid) != 0, if(pid() == 0 and if(pid1 == 0) assuming that the parent would have a return value of 0 for the the first fork and the children would have zero's for their respective forks) but this did not work. I checked their PID's and PPID's and they were all over the place).
All help is appreciated, thank you
So my programming assignment is to:
create 3 independent processes
have them send data to each other through pipes
when final data is sent, each of the three process will print their PID.
My question is, how do I get the processes to hold off so that the other processes can finish their tasks before terminating?
Is there a signal I need to send if the child is waiting?
Right now, I've got something like...
p1 = fork();
// For the first process
if (p1 == 0) {
// For the second process
p2 = fork();
if (p2 == 0) {
// For the third process
p3 = fork();
if (p3 == 0) {
}
}
}
// This is the parent
else {
}
Well your first child is forking the second child which is forking the next child, etc.
Is this really what's required here? It's difficult to say...is the parent supposed to have 3 direct children, siblings?
Here you're forking off this sort of ancestry,a child aving a child...parent with a grandchild, etc. If this is how it's supposed to be then the parent must wait for the first child to return...the first child must wait for it's child to return, and so on.
As for them outputting their PID...I'd say it was a simple case of having each individual child process output its PID.
All these things can be read about in great detail in the man pages and probably whatever coursework or lectures you attended prior to being given your assignment.
Best of luck.
Since each process is doing its own thing, which to me feels more like a "brothers/sisters" relationship. Is there a specific reason behind calling them parent process and child process?
Also, is it true that the parent process always run before the child process?
The parent owns the process group and thus spawns and reaps the children. Usually this process does a little bit of administrative work, while the children act as peers and siblings.
The naming is just convention for describing which process spawned the other, though.
The parent process and child process does the work based on your code but not because of parent or child relationship. When you execute fork() in the main thread it will create a child process, here the fork returns a value which is different in parent process and child process which can be used to differentiate the work of parent and child processes accordingly.
fork() always return pid of child in parent process and 0 in child process.
Coming to your second question it always depends on the scheduler as soon as the fork() is called and we cannot predict which process gets to run first after fork() function call.
Is there a specific reason behind calling them parent process and child process?
Well, since it one process (the parent) that creates the second one (the child), that might be the reasoning for the naming.
Also, is it true that the parent process always run before the child process?
The short answer. Nope.
I have been using this in all of my C-code
pid_t pid = fork();
if(pid == 0){ // child
// Child stuff
}else{ // parent
// Parent stuff
}
You might also want to use the
waitpid(pid, NULL, 0);
Parents are always before child. Sort and sweet!!!
fork() creates a copy of the current process which is a part of the process control group. The new process is subordinate to the originating process, for example when a child process dies, SIGCHLD is sent to the parent. Also, the clone is an inferior copy: for instance, any stored getpid() results will be inaccurate in the child; the child has a different parentid, the child has copies of the parent's file descriptors, and has independent resource usage counters.
The parent process, then, is always the one that made the call to fork(), if that's what you mean by run first. If you mean "will the scheduler always give the parent process slices first" then the answer is no.
See: http://gauss.ececs.uc.edu/Courses/c694/lectures/ForksThreads/forks.html, http://linux.die.net/man/2/fork
#include <stdio.h>
#include <unistd.h>
int main(int argc, const char* argv[])
{
pid_t otherPid;
printf("parent pid = %u\n", getpid());
otherPid = fork();
// in the parent, otherPid = the child's (new) process ID
// in the child, otherPid = 0.
switch (otherPid) {
case -1:
printf("Fork failed: %d\n", errno);
return errno;
break;
case 0: // child
sleep(2);
printf("child: my pid is %u\n", getpid());
break;
default:
printf("parent: pid is %u, child should have %u\n", getpid(), otherPid);
sleep(3);
break;
}
return 0;
}
What's the right way to tell a specific process to sleep?
I don't fully understand how to control the different processes I create..
I'm trying to make two processes that sleep for 2 and 3 seconds. When process 1 has slept for 2 seconds, and process 2 is still sleeping I want process 3 to start sleeping. But how do I tell a process to sleep? Or don't I?
int main(void)
{
pid_t p1 = fork();
pid_t p2 = fork();
pid_t p3 = fork();
//make p1 sleep(2) and p2 sleep(3)
waitpid(p1, NULL, 0); //waiting for p1 to terminate
//make p3 sleep(2);
}
As you can see I don't understand how to handle processes, or what they really are. I kind of see them as objects, but I'm guessing that's wrong.. I've tried reading some stuff about it, but they are all over 9000 pages PDF's.. A simple explanation of what I should see them as would be appreciated. And yes, this is school-material, but no, it's not an assignment.
Start with man fork which is slightly shorter than 9000 pages. The main thing is that successful fork returns two times: it returns 0 to the child process and the child's PID to the parent process. It's typically used like this:
pid_t pid = fork();
if (pid<0) { /* error while forking */
};
if (!pid) { /* code for child */
play();
whine();
sleep();
exit(0);
} else { /* code for parent */
grunt();
waitpid(...);
}
You don't normally tell the child process to do this and that, you just add code doing it to the appropriate if branch.
In your example, if all forks are successful, you end up with 8 processes:
First fork creates a new process, p1 gets 0 in the new process and some pid in the parent.
Second fork is called both in the original parent and in the child, adding 2 processes to the picture.
p2 gets 0 in all "grandchildren" and two different pids in 2 processes existing before step 2.
Third fork is called in four different processes, adding four other processes to the picture.
You could send it a SIGSTOP and then a SIGCONT I think.
kill(p1, SIGSTOP);
Alternatively and more sanely, since you're only forking and thus have complete controll over the code, you could handle the paths:
if (in_child_1)
sleep(..);
As a side note, in your code more processes are created than you expect. The thing is once p1 is created it starts executing from that point, in parallel with its parent. And so on.