I have the following program
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
main()
{
pid_t pid, ppid;
printf("Hello World1\n");
pid=fork();
if(pid==0)
{
printf("I am the child\n");
printf("The PID of child is %d\n",getpid());
printf("The PID of parent of child is %d\n",getppid());
}
else
{
while(1)
{
printf("I am the parent\n");
printf("The PID of parent is %d\n",getpid());
printf("The PID of parent of parent is %d\n",getppid());
}
}
}
The output of this program is parent runs forever without switching to child process. In this case why there is no switch to child process?
Ideally, the parent should wait for the child to finish, so that the child's process entry is properly reaped.
waitpid(pid, 0, 0);
To see if the child ever gets to run with your infinite loop. run the program and grep for child:
./a.out | grep child
Related
//Why not execute all the conditions(parent and child)?
#include<stdio.h>
#include<unistd.h>
int main(){
pid_t pid; //process-id
printf("This is where we start...\n");
pid = fork();
//For the child process
if(pid==0){
printf("This is the child process!\n");
return 1;
}
//This should have been printed
if(pid>0){
printf("This is the parent!\n");
}
//THis may/may not be printed - its ok
if(pid < 0){
printf("Fork failed!");
}
return 0;
}
It was excepted that after returning from the child, the parent should have been executed but this is what i get:
$ This is the child process!
What am i missing? why not child as well as the parent block printed?
The program is completely fine. When a fork is performed, a new child process is created. The child process created is independent of the parent and it is completely possible that the parent does not wait for the child to complete its execution.
If you want that the parent execution resumes once the child is complete, you should use the wait() function, that makes sure that a forked child is executed before parent continues.
Try updating your code as follows:
#include<stdio.h>
#include<unistd.h>
#include <sys/wait.h> //Add this header
int main()
{
pid_t pid; //process-id
int status; //A variable to get the status of the child, i.e. if error or success
printf("This is where we start...\n");
pid = fork();
if(pid==0){
printf("This is the child process!\n");
return 1;
}
if(pid>0){
wait(&status); //Function to wait for child
printf("This is the parent!\n");
}
if(pid < 0){
printf("Fork failed!");
}
return 0;
}
For more information check out this link: Forking a Process and Parent-Child execution - Linux : C Programming
I want to write an UNIX program that creates N child processes, so that the first process creates one child process, then this child creates only one process that is its child, then the child of the child creates another child etc.
Here's my code:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
int N=3;
int i=0;
printf("Creating %d children\n", N);
printf("PARENT PROCESS\nMy pid is:%d \n",getpid() );
for(i=0;i<N;i++)
{
pid_t pid=fork();
if(pid < 0)
{
perror("Fork error\n");
return 1;
}
else if (pid==0) /* child */
{
printf("CHILD My pid is:%d my parent pid is %d\n",getpid(), getppid() );
}
else /* parrent */
{
exit(0);
}
}
return 0;
}
The output that I expect is in the form:
Creating 3 children
PARENT PROCESS
My pid is 1234
CHILD My pid is 4567 my parent pid is 1234
CHILD My pid is 3528 my parent pid is 4567
CHILD My pid is 5735 my parent pid is 3528
The output I get in the terminal is
Creating 3 children
PARENT PROCESS
My pid is:564
CHILD My pid is:5036 my parent pid is 564
User#User-PC ~
$ CHILD My pid is:4804 my parent pid is 1
CHILD My pid is:6412 my parent pid is 4804
The problem is that the program doesn't seem to terminate. I should use Ctrl+C to get out of the terminal, which is not normal. Can you help me to fix this issue?
The children die when the parent dies.
In your case the parent exits before all the children have been created.
Try waiting for the children before exiting:
else /* parrent */
{
int returnStatus;
waitpid(pid, &returnStatus, 0); // Parent process waits for child to terminate.
exit(0);
}
try to wait the process with wait(NULL);
pid_t child = fork();
if (child == -1)
{
puts("error");
exit(0);
}
else if (child == 0)
{
// your action
}
else
{
wait(&child);
exit(0);
}
so your father will wait the child process to exit
The proposed cure is correct, but the reason stated is wrong. Children do not die with the parent. The line
CHILD My pid is:4804 my parent pid is 1
clearly indicates that by the time child called getppid() its parent is already dead, and the child has been reparented to init (pid 1).
The real problem is that after the child prints its message, it continues to execute the loop, producing more children, making your program into a fork bomb.
I have read this in books and also in some online forums that child process pid is assigned to its parent. But I have this code:
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
int main()
{
pid_t pid;
pid=fork();
if(pid==0)
{
printf("In Child Process\n");
printf("Child process PID : %d\n",getpid());
printf("Parent Process PID : %d\n",getppid());
}
else
{
printf("In Parent Process\n");
printf("Child PID : %d\n",getpid());
printf("Parent PID : %d\n",getppid());
}
}
It outputs:
In Parent Process
Child PID : 2061
Parent PID : 1830
In Child Process
Child process PID : 2062
Parent Process PID : 1161
But if I write a wait() function in else block, i.e:
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
int main()
{
pid_t pid;
pid=fork();
if(pid==0)
{
printf("In Child Process\n");
printf("Child process PID : %d\n",getpid());
printf("Parent Process PID : %d\n",getppid());
}
else
{
wait();
printf("In Parent Process\n");
printf("Child PID : %d\n",getpid());
printf("Parent PID : %d\n",getppid());
}
}
It outputs-
In Child Process
Child process PID : 2044
Parent Process PID : 2043
In Parent Process
Child PID : 2043
Parent PID : 1830
I'm not getting why the pid value returned by child process in first code is not the same as parent pid.
While in the second code, it is the same. Can someone please explain the reason for the above problem?
Remember that getpid returns the pid of the current process, and that getppid returns the parent pid of the current process.
So in the second example, when you call getpid in the parent process you get the pid of if itself (the parent process) and getppid gets the pid of the grand-parent.
The child pid is the value returned by fork.
More related to your problem is that you have no control over when a specific process runs in a modern multi-tasking system, which means that the child and parent processes may take turn printing out text. In your case it seems that the child process in the first example doesn't get to run until the parent process has printed its lines.
What the wait function does, is to actually wait until one child process has exited, and so the parent process will block until the child process has exited.
Joachim's answer is excellent. As additional note, you can get the child process' pid in the else branch by printing the result of fork:
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
int main()
{
pid_t pid;
pid=fork();
if(pid==0)
{
printf("In Child Process\n");
printf("Child process PID : %d\n",getpid());
printf("Parent Process PID : %d\n",getppid());
}
else
{
wait();
printf("In Parent Process\n");
printf("Child PID : %d\n", pid); // fork returns the pid of the child
printf("Parent PID : %d\n", getpid()); // because I'm the parent
}
}
First Example:
fork returns two processes, In your first example after fork the parent starts execution and prints its pid 2061 and parent pid 1830 (of bash) and the parent will terminate without waiting for the child to finish, So when child starts executing it will print its pid 2062 and its parent has already terminated it is printing some other pid.
You please sleep() before printing parent pid when child process is running and on other terminal use command ps -l to see which pid the child is printing as a parent pid.
Second example:
You are using wait in parent process that is parent will wait untill child terminates thus child process is printing the correct parentpid because parent is still not terminated.
Just got confused with parent pid value in child process block. My program is given below:
int main(int argc, char *argv[])
{
pid_t pid;
pid=fork();
if(pid==-1){
perror("fork failure");
exit(EXIT_FAILURE);
}
else if(pid==0){
printf("pid in child=%d and parent=%d\n",getpid(),getppid());
}
else{
printf("pid in parent=%d and childid=%d\n",getpid(),pid);
}
exit(EXIT_SUCCESS);
}
Output:
pid in parent=2642 and childid=2643
pid in child=2643 and parent=1
In "Advanced Unix programming" it says that child process can get parent process id using getppid() function. But here I am getting "1" which is "init" process id.
How can I get the parent pid value in the child process block.. Please help me in getting output.
I executed in "Linux Mint OS" but in "WindRiver" OS I am not getting this problem. Does this program change behaviour according to OS?
That's because the father can / will exit before the son. If a father exists without having requested the return value of it's child, the child will get owned by the process with pid=1. What is on classic UNIX or GNU systems SystemV init.
The solution is to use waitpid() in father:
int main(int argc, char *argv[])
{
pid_t pid;
pid=fork();
if(pid==-1){
perror("fork failure");
exit(EXIT_FAILURE);
}
else if(pid==0){
printf("pid in child=%d and parent=%d\n",getpid(),getppid());
}
else{
printf("pid in parent=%d and childid=%d\n",getpid(),pid);
}
int status = -1;
waitpid(pid, &status, WEXITED);
printf("The child exited with return code %d\n", status);
exit(EXIT_SUCCESS);
}
After the fork you have two new processes and you can know the child id in the parent but not the other way round. If you really need this you would have to open a pipe (popen) before the fork and then the parent could write this into the pipe and the child could read it.
Once the parent completes it execution and child is still running. Then child is known as orphan (as it's parent died) and it is adopted by init process if you are login by root ( whose pid =1 ).
If you want child to exit first before parent then use wait() system call and its variants.
#include <stdio.h>
#include <unistd.h>
int main()
{
int pid,pid2;
pid=fork();
if (pid<0) {
printf("fork failed");
exit(-1);
} else if (pid==0) {
printf("child id is%d",getpid());
execlp("/bin/ls","is",NULL);
printf("\nsleeping for 2 seconds using pid of child class");
sleep(2);
printf("killing the child process");
kill(getpid());
} else {
wait(NULL);
printf("The parent id is %d\n",getpid());
printf("The child id is %d\n",getpid());
printf("\nsleeping for 3 seconds without pid");
sleep(3);
printf("\nchild completed\n");
exit(0);
}
}
It is simply, because the parent process no longer exists. If you call the wait() system function, then it will exist until the child finishes its work and you will get the parent PID.
I was running the program
#include<stdio.h>
#include <unistd.h>
main()
{
pid_t pid, ppid;
printf("Hello World1\n");
pid=fork();
if(pid==0)
{
printf("I am the child\n");
printf("The PID of child is %d\n",getpid());
printf("The PID of parent of child is %d\n",getppid());
}
else
{
printf("I am the parent\n");
printf("The PID of parent is %d\n",getpid());
printf("The PID of parent of parent is %d\n",getppid());
}
}
THe output I got was.
$ ./a.out
Hello World1
I am the parent
The PID of parent is 3071
The PID of parent of parent is 2456
I am the child
The PID of child is 3072
The PID of parent of child is 1
I couldnt understand the line
The PID of parent of child is 1
It should have been 3071?
Because parent process is finished by the time the child asks for its parent's pid.
When a process finishes, all its children are reassigned as children of the init process, which pid is 1.
Try using wait() in parent's code to wait for the child to execute. It should then work as you expect.
pid 1 is for init process and it looks like the parent process finished before the child could print.
If you edit the else part like this :-
else
{
printf("I am the parent\n");
printf("The PID of parent is %d\n",getpid());
printf("The PID of parent of parent is %d\n",getppid());
while(1);
}
You should see the right output.