I am trying to understand the re-parenting process in linux. So when the parent process exits abruptly the child process is adopted by the init process. This is re-parenting.
I am not able to understand the below code that shows how re-parenting works.
First the process is forked and the child process runs.
The first "printf" statement is executed.
Then sleep() is called. Why is "terminated" printed after this?
Is the parent process ever called?
Please somebody explain me how does this work?
#include <stdio.h>
#include <unistd.h>
int main() {
if (fork() == 0) {
// child process
printf("My parent's PID is %d\n", getppid());
sleep(2);
printf("My parent's PID is %d\n", getppid());
} else {
// parent process
sleep(1);
}
// both processes
printf("Terminated\n");
}
The output:
My parent's PID is 18892
Terminated
shell $ My parent's PID is 1
Terminated
Related
This question already has answers here:
Create zombie process
(2 answers)
Closed 1 year ago.
my task is to create zombie process. My code looks like this:
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
int main() {
pid_t pid = fork();
if (pid == -1) {
printf("error\n");
}
else if (pid == 0) {
printf("Child %d\n", getpid());
printf("Parents %d\n", getppid());
printf("Waiting for my Child to complete\n");
exit(0);
}
else {
sleep(5);
printf("Parent %d\n",getpid());
}
return 0;
}
When I gcc and execute the file with ./a.out I get the following output:
Child 25097
Parents 25096
Waiting for my child to complete
Parent 25096 ( a few seconds later)
My task is to create a zombie process and print out the exit-state of the child process while being in parent process. Everything is a bit confusing to me because its the first time for me using Linux and C.
Do you have some tips/ hints for me, how to solve the task? Cause I'm not sure if everything is right. I also tried playing with wait(), waitpid() and WEXITSSTATUS(), but I'm not sure about it. And I used the ps x command to check if there is a different output but I didn't notice any changes.
Thanks in advance :)
This code will successfully create a zombie process.
After the call to fork, the child prints a few lines and exits, while the parent sleeps for 5 seconds. This means you'll have a zombie process for about 5 seconds while the parent is sleeping.
When the sleep is done, the parent prints something and exits. Once the parent exits the child is inherited by the init process, which will wait for the child and make it's pid disappear fro the pid list.
You can also use wait in the parent process, in which case the child is a zombie up until the parent calls wait.
I'm working on c program which uses fork() and wait() calls, firstly I created five child processes and then I called wait() for five times. Whenever I execute the program it prints the same child process id in the second for loop which is displayed from the first for loop. The child processes were never getting exited before the wait() function is getting called. Why is this happening? Why the cpid is always printing the exact child process id which were displayed before?
code :
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
int main( )
{
int child_pids[5];
int i;
printf("PARENT ID: %d \n", getpid());
for(i=0;i<5;i++) {
if(fork()==0) {
printf("child(pid): %d of parent(pid): %d \n",getpid(),getppid());
exit(0);
}
}
for(i=0;i<5;i++) {
int cpid=wait(NULL);
printf("parent (pid): %d waited for child(pid): %d \n",getpid(),cpid);
}
return 0;
}
If there are any mistakes in my way of asking questions, please comment below
Upon exit, the child leaves an exit status that should be returned to the parent. So, when the child finishes it becomes a zombie.
Whenever the child exits or stops, the parent is sent a SIGCHLD signal.
The parent can use the system call wait() or waitpid() along with the macros WIFEXITED and WEXITSTATUS with it to learn about the status of its stopped child.
If the parent exits, than you can see your children still as zombie processes (unwaited children ).
wait() just tells you which child exited so you can get the exit code. If you have more children running, then of course, others could have terminated in the meantime as well.
If you don't care about the exit status, then wait() is just fine, but you still have to wait on all children you started.
I saw this similar question, which says that the child process won't be automatically killed when the parent process exits. So I wrote a simple program trying to validate that:
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
int main() {
if (!fork()) {
while (1) {
printf("%d: child!\n", getpid());
sleep(5);
}
}
while (1) {
printf("%d: parent!\n", getpid());
sleep(1);
}
return 0;
}
When I ran the program, the output is like this:
8056: parent!
8057: child!
8056: parent!
8056: parent!
8056: parent!
8056: parent!
And I hit ctrl + C, expecting that the parent process will be killed but child process still around. However, after I hit ctrl + C:
The program exited immediately, I was expecting that child process would still write to the terminal if it is not killed. Moreover:
Neither 8056 or 8057 were shown in the process list.
Does it mean that the child process will be automatically killed when parent process exits? Or did I miss any process management details in a C program?
I want to write a program in which the parent creates exactly 1 child process. The child process should print its pid to the standard output and then finish. The parent process should waits until it is sure that the child has terminated. The parent terminates after it has waited for the child process.
Thats what I got so far:
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
int child;
child = fork();
if (child == 0)
{
printf("Child process has PID: %d. \n", getpid());
exit(0);
}
// how can the parent process find out it the child process was terminated successful?
printf("Child process terminated successfully\n");
return EXIT_SUCCESS;
}
How can the parent-process find out if the child process was terminated? I can't use wait() or waitpid() in this programm.
Thanks for your help!
When a child process terminates a SIGCHLD signal will be sent to the parent, by default the parent will ignore the SIGCHLD, however you can register a signal handler that will catch it.
You need to be careful what you do in the signal handler - quite a few standard function aren't safe to use.
The SIGCHLD approach turns up in code when the parent has it's own work to do and can't just wait for the child. If the parent just spawns children and then waits for them to finish the wait() and waitpid() are the best solution.
Finally if you don't call wait() or waitpid() you risk creating a zombie process, the child process expects it's parent to receive it's exit status through a call to one of these functions.
As I said in remark use the signal SIGCHLD, for instance :
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
void handler(int sig)
{
pid_t chpid = wait(NULL);
/* WARNING : to show the call of the handler, do not do that
in a 'real' code, we are in a handler of a signal */
printf("Child pid %d ended (signal %s)\n", chpid, sig);
/* does 'something' to allow the parent to know chpid
terminated in a way compatible with parent requirement */
}
int main(void)
{
signal(SIGCHLD, handler);
if (!fork())
{
printf("Child pid is %d\n", getpid());
sleep(1);
return 0;
}
printf("Parent pid is %d\n", getpid());
getchar();
return 0;
}
Note when the signal arrive you have to call wait(NULL) but because by definition the child terminated the function returns immediately
Compilation and execution :
pi#raspberrypi:/tmp $ gcc -pedantic -Wall -Wextra s.c
pi#raspberrypi:/tmp $ ./a.out
Parent pid is 21743
Child pid is 21744
Child pid 21744 ended (signal 17)
<enter>
pi#raspberrypi:/tmp $
Of course the signal 17 is SIGCHLD because it is the only one the program catches
#include <stdio.h>
#include <unistd.h>
int main()
{
pid_t pid;
pid = fork();
printf("pid : %d\n", getpid());
if( pid == 0)
{
printf("child: pid : %d \n", getpid());
while(1);
}
else
{
printf("parent: pid : %d \n", getpid());
//while(1);
}
}
In the above code snippet inside if statement if we put while(1), it doesn't remains blocked and when enter key is pressed program is exited, but in case of parent if we put while(1), parent remains blocked until we give ctrl+c. Please clarify this behaviour of child.
In the above code snippet inside if statement if we put while(1), it doesn't remains blocked
The child process doesn't exit actually; it just becomes an orphan process because its parent exits. The orphaned chuld process will be adopted by the init process of your system. You can see it via ps command.
But if you put the while(1); in the parent process it remains blocked.
Basically whichever process has while(1); infinite loop, it's still running. When parent exits you get the prompt back and the child becomes orphan. But the child process is still running.
In general, you need to wait(2) for the child process in the parent process to reap child processes.