Why do I get 0 instead 1 in after fork? - c

I have the program that increases the number by one.
int ile=0;
pid_t pid = fork();
if(pid != 0) {
ile++;
printf("%d", ile); //I get 1
}
else {
printf("%d", ile); //I get 0
}
Why do I get 0? I must get 1.

fork () creates a new process with its own address space. These are not threads that share a common address space. If you want the latter behavior look at something like pthreads.
Changes in the parent process (ile++ in your case) after a fork() isn't going to be visible in the child.

Related

saving the returnin value of fork in a variable in C [duplicate]

This question already has answers here:
How does fork() know when to return 0?
(5 answers)
Closed 5 years ago.
I am a bit confused about the value which the function fork returns. I understand that value 0 is for child process and value >0 is for parent process.
I have the code below
int main()
{
int pid;
pid = fork();
if(pid == 0)
//DO SOMETHING
else
//DO SOMETHING ELSE
return 0;
}
The valiable pid after fork is different for each process ?
I can't understand how it switches value. And I have a second part with code
int main()
{
int pid;
if (pid == 0)
{
return 5;
}
printf("parent = %d waits for child = %d ", getpid(), pid);
waitpid(pid, NULL, 0);
printf("child terminates!")
return 0;
}
in which I can't understand why pid on line with first printf has the value of child. It shouldn't be the id of parent ?
The valiable pid after fork is different for each process ?
Yes, that's the new process ID you get as the return value. There can't be same processes with the same ID at the same time, so whenever you fork your usually get an unique one.
The process is cloned while still inside the fork() call, including copies of all variable memory contents (heap, stack, data segments). Once the copy is completed, the kernel resumes execution of both processes, but gives different return values.
in which I can't understand why pid on line with first printf has the value of child. It shouldn't be the id of parent ?
getpid() returns the ID of the parent, since that is the context in which you are executing it now. pid is just garbage (uninitialized memory) in that example, so whatever you think you are seeing, it's not an process ID but only some random memory content.

Understanding how fork() and wait() work together

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.
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.
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.
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.

Uneven tree of processes using fork()

I have to construct a tree of processes using fork() in C. I get a sequence of numbers from standard input (for example: 1 5 0 3) and those numbers tell me how many children each node has. If we take the example then the root process creates 1 child, then this one child creates 5 children of its own, then from those 5 children the first one doesn't create any children, the second one creates 3 of them and then we're done. After this is complete the root process calls pstree that draws out the tree.
Here is a picture of the example:
My question is how can I make new children from a specific node? One needs to create 0 new processes and the next one needs to create 3 of them. I don't know how to distinguish so that only that specific child makes new children and not all of them. Also I'm not sure how to use pstree, because the tree is normally already gone when pstree gets called. I know I can wait() for children to execute first but last ones do not have any children to wait for so they end too fast.
I've written code that creates the example. Need ideas how to generalize this for different inputs. Also can someone show me how to call pstree from this code because I can't seem to get it working.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
int main() {
pid_t pid;
pid_t temppid;
pid_t temppid2;
int root_pid;
int status;
root_pid = getpid();
pid = fork(); // creates a child from root
if (pid == 0) { // if child
pid = fork(); // fork again (child#1)
if (pid != 0) { // if not child of child#1
temppid = getpid(); // get pid
if (getpid() == temppid) { // create child#2
pid = fork();
if (pid == 0) {
temppid2 = getpid();
if (getpid() == temppid2) { // create child#1
fork();
}
if (getpid() == temppid2) { // create child#2
fork();
}
if (getpid() == temppid2) { // create child#3
fork();
}
}
}
if (getpid() == temppid) { // create child#3
fork();
}
if (getpid() == temppid) { // create child#4
fork();
}
if (getpid() == temppid) { // create child#5
fork();
}
}
}
else {
// create another child from root
pid = fork();
if (pid == 0) {
// run pstree in this child with pid from root
}
}
while (1) {
sleep(1);
}
}
For pstree, the solution is simple - every process, after doing what it should, would go to sleep (for, say, a minute).
Then you can use pstree to see what's going on.
For forking the right number of times, it seems that the problem is with parsing the input, not with forking.
I'd start with writing code that reads the input and, instead of forking, just prints the tree of processes you want to create. Once you have this clear, it shouldn't be able to do the forks right.
For just testing the hierachy your app created:
Instead of placing a
return 0;
as last statement put a
while (1)
sleep(1);
This make the process run for ever until you press Ctrl-C.
After you started the app use another terminal and issue a pstree to inspect the process hierachy the app created.
To clean up (and if on linux) issue a killall <app name>.
My one suggestion is that you use the return value of fork to tell if your code is running in the child process or parent process.

C: printf (with fork())

In the next code:
int i = 1;
fork();
i=i*2;
fork();
i=i*2;
fork();
i=i*2;
printf("%d\n", i);
Why 8,8,8,8,8,8,8,8 is printed, and not 1,2,2,4,4,8,8,8? fork() duplicate the process, and print the i before each fork. What I miss?
Given the code shown, you should be seeing eight lots of 6 (you wrote i = i + 2; instead of i = i * 2; for the last computation.
Since each process follows the same code path, each process will produce the same result.
To get the result you expected, you'd have to track whether each fork() yielded the parent or child process:
int i = 1;
if (fork())
{
i=i*2;
if (fork())
{
i=i*2;
if (fork())
i=i*2; // + --> *
}
}
printf(|%d\n", i);
I'm assuming there are no problems with the fork() operation. It is also interesting to note that you could invert any or all of the conditions and end up with the same result.
Because fork continues to execute the code as it goes downwards. So each of the processes will run through the i = i * 2 each time as they spawn off more children. Making it what you get and not what you expected (i.e. it doesn't jump to the end of the block once forked).
Info on fork: http://www.csl.mtu.edu/cs4411/www/NOTES/process/fork/create.html
Each new process gets a copy of the stack of the parent, so immediately after calling fork(), both parent and child have the same value for i -- but they don't have the same stack, just a copy... so changing i's value in one process has no effect on the other.
If you want two parallel pieces of code to share the same memory, either use threads (and memory that's in the heap, not on the stack), or use an explicit shared memory region.

Segments duplicated during fork()?

I have studied that during a fork, the data and code segment of the parent process gets duplicated into the child process.
Kindly see the program below.
int main()
{
int a = 5;
pid_t pid;
pid = fork();
if(pid == 0)
{
printf("In child a = %d",a);
}
else
{
printf("In parent a = %d",a);
}
return 0;
}
Here a is in the stack segment of parent process as it is declared inside the function, main(). The child process should only get copy of the code and data segment of the parent process and not the stack during fork(). But when I run the program, I can see that the child process is able to access the variable 'a' also. Thats means somehow the stack of parent process is also copied into the child process.
Kindly tell me the reason for this and correct me if my understanding is wrong.
You should check the docs again. fork creates an "exact copy of the calling process". Admittedly, there are a lot of exceptions, but the stack is not one of them.
Also, if the stack wasn't duplicated, the very common idiom (also used in your code) of checking the return value (almost always a stack variable) from fork would fail. There wouldn't be a stack position for pid unless the stack (including stack pointer) was duplicated.
That isn't a good test - as Matthew has pointed out, fork() gives you an exact copy of the parent process, including the stack (else the child would be unable to return from this function).
A better test is to modify 'a' in the parent and observe it in the child, like this:
#include <stdio.h>
#include <unistd.h>
int main()
{
int a = 5;
pid_t pid;
pid = fork();
if (pid == 0)
{
sleep(5);
printf("In child a = %d\n",a);
}
else
{
a++;
printf("In parent a = %d\n",a);
}
return 0;
}
and the result is correct:
pandora:~/tmp$ cc -o x x.c
pandora:~/tmp$ ./x
In parent a = 6
pandora:~/tmp$ In child a = 5

Resources