Pid after fork in C [duplicate] - c

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.

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.

C - Child Process Not Executing

[SOLVED]
So for this practice exercise I was assigned we are practicing process control. I'm simply wondering why it seems that my child process will never execute (when child_pid == 0). Any help on this issue would be greatly appreciated!
Also, safe_fork() is a function our instructor wrote in order to avoid students opening too many processes.
#include "safe-fork.h"
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
int main(void) {
pid_t child_pid;
int pipefd[2];
int pipe_result;
int count;
pipe_result = pipe(pipefd);
if (pipe_result == -1) {
perror("pipe failure");
exit(1);
}
child_pid = safe_fork();
/*Parent Process*/
if (child_pid > 0) {
dup2(pipefd[0], STDIN_FILENO);
scanf("%d", &count);
if (count > 200) {
printf("Long enough!\n");
exit(0);
}
else {
printf("Too short!\n");
exit(1);
}
}
/* Child Process */
else {
dup2(pipefd[1], STDOUT_FILENO);
execl("/usr/bin/wc", "-w");
}
return 0;
}
Here is a suggestion, check for child_pid == 0 explicitly cause it could also be the case that your safe_fork() function failed, also check for those errors i.e child_pid < 0.
Add debug printf statements to check control flow if you already haven't and finally check if the execl call failed.
Also please have a look at this tutorial for creating pipes in C and using them to communicate between a parent and a child process. As I feel there are some issues with how you are handling those file descriptors. A possible reason that you can't see any output is that wc might still waiting for some input.
And another thing you might need to wait for the child process to complete/do something useful or actually be run before checking for its output. Check the other issues first before you worry about this.
Hope this Helps :)
Yes, But no. First you should carefully understand the meaning of fork().
fork(): creates a child process and it returns into TWO PROCESSES, with different return value in each. In parent, it always returns the number that OS has assigned for the newly created child's process id. At the same it returns in newly created child also, as child process will start executing the code copied from parent just after the fork() statement. In child fork always returns zero. So normally after a fork() system call, people check for returned value by fork to differentiate child process and parent process.
particularly in this case after a fork(), there will be two processes with same code and same program states(except both will have different value assigned in child_pid variable). In parent its a non zero value (which is corresponding to child's pid) and in child, its the value zero as the fork returns zero in child.
Now both processes will execute
if (child_pid > 0)
which is true only for parent so parent process will flow into 'if block' and is false for child so it will directly jump to else part and will execute the else block.
What if child_process id is zero?
OS will always assign a non zero value for a child so that fork() will work. And if you have somehow got child process id as zero then parent will fail to enter in 'if block' and will execute else block which is the same as child.

In C programming language, how can variable store two values? [duplicate]

This question already has answers here:
How is it possible for fork() to return two values?
(5 answers)
Closed 7 years ago.
I've decided to learn C, and here is the snippet from one of the books that I use:
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
int main()
{
pid_t result = fork();
if (result == -1){
fprintf(stderr, "Error\n");
return 1;
}
if (result == 0)
printf("I'm a child with PID = %d\n", getpid());
else
printf("I'm a parent with PID = %d\n", getpid());
return 0;
}
Its output is:
I'm a parent with PID = 5228
I'm a child with PID = 5229
Everything's clear, but how could it be that result == 0 and result != 0 at the same time? It looks like this variable stores two values, because the printf instruction is executed twice. I know, that fork() returns 0 and a parent's PID, but how does result check if it returns true for different conditions?
Because it's not the same variable. When you fork a process, you end up with two totally different processes (see this answer for more detail).
Hence the result variable in the parent is not the same as the one in the child. What you're seeing is two processes, both attached to the same output device, each writing their own message.
In fact, the fork documentation specifically covers that:
On success, the PID of the child process is returned in the parent, and 0 is returned in the child.
So you can use the return value from fork (as you do) to see if you're the parent or child (and to see if it worked as well, it'll return -1 if it fails and you'll be the parent with no child).
The idea is that the parent gets the process ID of the child so it can do something with it (like wait() for it to finish) and the child gets zero. The child can always get the process ID of the parent by calling getppid().
A variable can only hold a single value at a time. What you're seeing is happening because fork() is creating another process: there's now two instances of your program running; one in which result == 0 (the spawned process), and another where result != 0 (the original process)
fork replicates a child from a parent. So the newly created child inherits several properties like shared memory, message queue, file streams etc from the parent. So when you call fork, another process with another variable result is created.
The fork() function create a new process, after this line your program split to 2 from that spot. Because you need to know which process are you, the function return 0 if you are the child process, and some pid if you are the father process.
from the man page:
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, and errno is set appropriately.
fork() function will create a new process. in parent process, fork() will return the pid of child process, so "result" variable will not equal with 0, and in child process, fork() just return 0, so "result" is 0.

Why does return value of fork() have 2 pid value in C? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How is it possible for fork() to return two values?
I'm new to C, and I'm confused about the return value structure of the fork() function.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(){
pid_t childPid;
childPid = fork();
printf("%d\n",childPid);
return EXIT_SUCCESS;
}
The output is:
28501
0
Since pid_t is an int type, how does the childPid have 2 values?
You're actually seeing the output of two copies of the executable. When you call fork(), the process clones itself, giving two processes. The parent gets the child process's PID as the return value, and the child gets 0 as a return value.
The trick is, the clones share STDIN, STDOUT, and STDERR. When the parent reaches the printf, it prints the value it had, as does the child, so you see both PIDs, with both processes sharing the same STDOUT -- there's no obvious way to tell them apart in your program.
Try rewriting it as:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(){
pid_t childPid;
childPid = fork();
if(childPid != 0)
printf("I'm the parent and my child PID is %d\n",childPid);
else
printf("\tI'm the child, so I received %d\n",childPid);
return EXIT_SUCCESS;
}
and you'll see this more clearly.
For extra credit, look at the wait() syscall, and use it to make the parent terminate after the child.
After a successful fork, you have two processes, parent (forker), and child. The newly created process, the child, gets a return value of 0. This is the signal that it's the child.
So you're seeing the parent process printing the child's actual pid, and the child process printing 0. This is working as expected, unless I'm missing something in your question?

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