How many processes are created in the program when using fork() in a condition? - while-loop

I'm having trouble to understand how fork() works when it is used as a condition. I know that fork() creates a child process as an exact copy of the parent process. My question is, how many processes are created in the following program? Here is the code:
int global = 0;
int main() {
while(global < 5 && !fork()) {
sleep(1);
global += 1;
}
printf("%d\n", global);
return 0;
}
I was a assuming that for each fork() call, every process that is already running will create a child process and continue like that as long as the variable global reaches the value of 5.

The fork() call returns 0 in the child and the pid of the child in the parent.
Therefore, in the parent, the second condition will evaluate to 0, and the loop will exit and then print. In the child, the second condition will evaluate to non-zero, and the loop will fork again with a higher value of global (which is inherited).
Thus, we will see a total of 5 new processes in addition to the parent.

Related

Sending a SIGSTOP to child process

I am learning about sending signals. I came across SIGSTOP and SIGCONT to pause and then continue a running process respectively.
As far as I understand, when we execute a fork(), we do not know whether the parent or the child would execute first. It is dependent on the architecture of the process scheduler. This is why if for example after the fork we print something separately in the parent and child, the order of execution cannot be determined. (Unless we are using wait() in parent to synchronize the two processes).
Now, I am sending a SIGSTOP signal from parent to child and then after the parent has done some computation, sending a SIGCONT signal to child to resume operation. So far, every time I run the code, no code under the child process executes. But I am wondering if this will always be the case? Could there be a situation where an instruction in the child process gets executed before it receives the SIGSTOP from its parent? Here is some sample code:
pid_t pid_c = fork();
if (pid_c == 0){
printf("Hello I am the child process!\n");
}
else {
kill(pid_c, SIGSTOP);
printf("Hello I am the parent process!\n");
// do some computation
kill(pid_c, SIGCONT);
wait(&NULL)
}
When I try executing the above code, the parent process always starts with printing the statements so the SIGSTOP is able to pause the child execution before it can execute anything. Does this always happen with SIGSTOP or is this just architecture dependent? I mean could there be a case where the child prints "Hello I am the child process!" before getting paused?
Any suggestions are much appreciated! Thank you!

I don't understand how stdio buffering interacts with child processes

I think the output should be first child process should be executed the second child then parent but on compiling it gives the first line of first child and then first line of second child then again second line of first child and second line of second child. Here is the code in question:
#include<stdio.h>
int main() {
int pid,dip;
pid=fork();
if(pid==0) {
printf("1st child's process id is %d \n",getpid());
printf("first child dead");
} else {
dip=fork();
if(dip==0) {
printf("2nd child process id is %d\n",getpid());
printf("Second child dead");
} else {
printf("Child with pid %d died \n",wait(0));
printf("Child with pid %d died \n",wait(0));
printf("I am the parent");
}
}
return 0;
}
The order of execution there is indeterminate. There are three processes, the parent, and two children. So there are 3! = 6 possibilities in terms of what order they complete in.
If you run that code enough times, you'll see all 6 such possibilities, although there may be a tendency toward one or two in particular.
Since there are several printf()s -- one of which is not flushed with a newline -- in each process, there are more that just 6 possibilities WRT what order these lines appear in. Two lines from the same process will always be sequential (i.e., the first will appear before the second) but a line from another process could appear in between them.

Process creation tree for this code?

What's the process creation tree for this code (assuming all forks succeed)?
if(fork())
fork();
n = 3;
for(i=1;i<n;++i)
{
if(pid = fork())
break;
}
This is what I tried:
[0]
|
/\
[1] [1]
| |
[2] [2]
| |
[3] [3]
|
[4]
But that wasn't even one of the choices! Any help is appreciated.
First line:
if (fork())
After this fork, there are two processes, the parent and the child. In the parent, fork() returns nonzero. In the child, fork() returns zero. This means that the next line will run only in the parent.
fork();
The parent forks again. Now there are three processes, and all three will run the rest of the code.
for(i=1;i<n;++i)
{
if(pid = fork())
break;
}
First, i=1. Each of the three processes creates a child, sees a nonzero result, and breaks out of the loop. So the original three processes are done. But the children will keep going.
Next time through the loop, i=2. The same thing happens. Each of the three child process forks off a child of its own, sees a nonzero result, and breaks. The three new children will keep going.
And so on up to i=n-1.
I'll spare you my attempts at ASCII art, but the resulting tree looks a bit like a certain familiar piece of silverware...

Process Synchronisation using semaphores

Here is the problem.
I want two processes to occur alternatively, the complete problem is here.
Q. In a system ther are two processes named A and B.When the system starts,the process A executes twice then process B executes once.The Process B cannot execute until process A has executed twice. Once Process A haas executed it can not execute again until process B has executed. The restriction mentioned above allows the process A and B to execute in the following manner.
AABAABAAB...
Write the pseudocode for Process A and B using counting semaphore to achieve the desired synchronisation.
Here is my attemp for this.
Solution:
Process A
var a=1,b=0,i;
begin
repeat
wait(a);
for(i=0;i<2;i++)
printf("A"); // conidering this is what process a does.
signal(b);
forever
end
Process B
begin
repeat
wait(b);
printf("B"); //considering this is what process B does.
signal(a);
forever
end
Is this correct?
An alternative solution would be:
Semaphore as = 1;
Semaphore bs = 0;
A() {
int counter = 0;
while(TRUE) {
if(counter % 2 == 0)
P(as);
print("A"); // and whatever A does
counter++;
if(counter % 2 == 0)
V(bs);
}
}
B() {
P(bs);
print("B"); // and whatever B does
V(as);
}
The idea is that A waits for B on every 2nd turn (execept the 0th).
I think that the general idea is correct, but the terminology is rather strange. Wait-signal pair is usually used for condition variables (although e.g. POSIX semaphorese use post/wait).
I suggest you substitue the wait with semaphore_down and signal with semaphore_up.

create a process tree in C

How would I approach creating a process hierarchy that would look like a balanced ternary tree of depth N? ... meaning each process has 3 children so there would be (3^N-1)/2 processes in a tree of depth N. To create the new processes, I only want to use fork().
This is what I have so far but I don't think it works because I don't deal with process IDs and also I really don't think I should do this recursively:
void createTernaryTree(int n) {
if((n-1) == 0) return;
else {
int x;
for(x=0; x<3; x++) {
fork();
createTernaryTree(n-1);
}
}
}
Thanks,
Hristo
This bit does not look right to me:
for(x=0; x<3; x++) {
fork();
createTernaryTree(n-1);
}
The problem is that both the parent and the child continue looping and do the recursion.
Based on the return from fork (0 in the child, > 0 in the parent, -1 on error), you should decide whether to loop or recurse.
The code shown would do the job The code shown would nearly do the job (but there's a subtle problem). The other difficulty would be showing that it does the job.
The problem is that the code doesn't behave differently for the child and the parent processes after the fork. The parent process needs to complete its loop. Each child needs to restart a loop at the next level:
for (int x = 0; x < 3; x++) // C99
{
if (fork() == 0)
{
createTernaryTree(n-1);
break; // Per comment from R Samuel Klatchko
}
}
pause(); // See below
You could (should) add a 'pause();' call after the loop; this would send the parent process into suspended animation until it receives a signal. You could then show that you have a tree of processes. Alternatively, use 'sleep(30)' or some other way of suspending the processes. You don't want them to exit immediately; they'll do that too quickly for you to be able to demonstrate the tree structure.
In theory, you might want to track whether 'fork()' succeeds; in practice, it isn't clear what you'd do differently except, perhaps, not try to create the second child if the first fails (but that's likely to fail anyway, so blindly trying is probably best in the circumstances - but remember that in other situations, it would usually matter a lot).
Trees are inherently recursive structures; using recursion to manage them is often the neatest way to deal with them. This looks like it is tail recursion which means that it can be converted into a looping structure fairly easily. However, managing a data structure to keep tabs on what is happening is going to be harder than just doing it recursively.