Segments duplicated during fork()? - c

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

Related

Pid after fork in C [duplicate]

This question already has answers here:
How does fork() work?
(5 answers)
Closed 5 years ago.
I scripted this simple code in C to emulate what happens after a fork in Linux
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
int value = 5;
int main()
{
pid t pid;
pid = fork();
if (pid == 0) { /* child process */
value += 15;
return 0;
}
else if (pid > 0) { /* parent process */
wait(NULL);
printf("PARENT: value = %d",value); /* LINE A */
return 0;
}
}
It works, even if i dont understand how the fork() succed in giving different PIDs to parent and child processes. Is it connected to the "shared memory segment" beetween parent and child processes ?
Can you explain me ?
After a successful call to fork, a new process is created which is an exact duplicate of the calling process. So the function actually returns twice, once to the parent and once to the child, with the parent's return value being the PID of the child and the child's return value being 0.
The new process does not however share data with the parent. All constructs, including the stack and global variables, are distinct from those in the parent.
In this case, the child process adds 15 to value. This variable is however completely separate from value in the parent process. So when the parent prints value, it prints the value that the parent has, which is 5.

Another Fork() program in C

So I am continuing some more problems on Fork() and found some sample code on a website called geeksforgeeks. The following code segment:
#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
void forkexample()
{
int x = 1;
if (fork() == 0)
printf("Child has x = %d\n", ++x);
else
printf("Parent has x = %d\n", --x);
}
int main()
{
forkexample();
return 0;
}
Now I can see why the solution can be either Child has x = 2 and Parent has x = 0 but I am having some issues trying to visualize the tree. The big problem that I have visualizing this is that the first if statement is for the child process, so how would the tree look? Here is what I have come up with in terms of a visualization of this program.
Or would the main node on Level 0 be a Child node because of the order of the if statement coming first (this is a possibility but the else statement could come first as well as it is running concurrently).
Any help? Is this visualization correct or is there something I am missing?
Would appreciate the help , thank you.
No, your visualization is wrong.
After the fork you have TWO processes: Parent and Child. (PERIOD)
A single parent may spawn multiple children, and each may spawn children of their own. But after a single fork, the "tree" is two "nodes".
Not sure if you are trying to graph:
Processes over time, then YES, you are correct, one process has become two.
Process relationship, then NO, you should only have one parent, one child.
Execution path, I guess... at some point fork() is called, next thing you know, you have two processes executing the if() statement.
I don't see where the question is here..
The schema is good it's like this. Fork() creates a new process by duplicating the calling process. On success, the PID of the child process is returned in the parent, and 0 is returned in the child. On failure, -1 is returned in the parent, no child process is created (google). You must check the return value to be sure that you're in the child process which is running independently.
Try this :
#include <unistd.h>
int main()
{
pid_t p;
int x;
x = 1;
p = fork();
printf("pid = %d\n", p);
if (p == 0) {
printf("Child has x = %d and pid = %d\n", ++x, p);
sleep(1);
} else {
printf("Parent has x = %d and pid = %d\n", --x, p);
sleep(1);
}
}
They are executed at the same time because they are independant but the parent is primary at the ouput
Nicolas

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.

C programming child process is not executing

So this is simple program of creating two process: parent and child. So what I did is have the greeting inside the parent and the name inside the child process. For some reason my child process is not printing despite that I called wait() inside the parent. What should I do?
GOAL OUTPUT: "Hello Sam"
OUTPUT I"M GETTING: "Hello"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
char *greeting = "Hello";
char *name;
pid_t pid;
pid = fork();
if(pid == 0)
{
name = "Sam";
exit(0);
}
else if(pid == -1)
printf("Fail\n");
else{
wait(0);
printf("%s %s", greeting, name);
}
}
When you make a call to fork(), the child process will receive a copy of the parent process' address space (variables etc...). This means that in the child, "name" is defined, from the parent. However, "name" in the child process is just a copy. So modifying it in the child process does not affect the parent.
To get the behavior that I sense you're after, replace fork() with vfork(). For the purposes of this discussion, the only difference is that:
The address space is shared instead of copied. Editing "name" in the child process will be reflected in the parent process
The parent process is suspended while the child process executes. I assume that this is OK, because you are already calling wait() in the parent process
Edit:
I forgot to add that if you go the vfork route, change exit() to _exit() in the child process
Child process once forked will run independantly of the parent process. So when you set name="Sam" in child it is in different program, than the printf. So you are not able to see the message.
In the child process, you assigned to name and then exit.
if(pid == 0)
{
name = "Sam";
exit(0);
}
The printf("%s %s", greeting, name); line is executed only in the else branch, i.e, the parent process. It's actually undefined behavior because name is uninitliazed.

Why do I get 0 instead 1 in after fork?

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.

Resources