- Memory Mapping
- Signals
- Semaphores
- Message Queues
- Shared Memory
- Named Pipes
- Pipes
- System V & Posix
- Related System Calls (System V)
- Overlaying Process Image
- Other Processes
- Process Resources
- Process Groups, Sessions & Job Control
- Child Process Monitoring
- Process Creation & Termination
- Process Image
- Process Information
- Overview
- Home
Useful Resources
Selected Reading
- Who is Who
- Computer Glossary
- HR Interview Questions
- Effective Resume Writing
- Questions and Answers
- UPSC IAS Exams Notes
Other Processes
So far, we have discussed about processes, its creation, parent and child processes, etc. The discussion will be incomplete without discussing other related processes, such as the Orphan process, Zombie process and Daemon process.
Orphan Process
As indicated by the name, orphan imppes parentless process. When we run a program or apppcation, the parent process for the apppcation is shell. When we create a process using fork(), the newly created process is the child process and the process that created the child is the parent process. In turn, the parent process of this is shell. Of course, the parent of all the processes is init process (Process ID → 1).
The above is a usual scenario, however, what happens if the parent process exits before the child process. The result is, the child process now becomes the orphan process. Then what about its parent, its new parent is the parent of all the processes, which is nothing but init process (Process ID – 1).
Let us try and understand this using the following example.
/* File Name: orphan_process.c */
#include<stdio.h> #include<stdpb.h> int main() { int pid; system("ps -f"); pid = fork(); if (pid == 0) { printf("Child: pid is %d and ppid is %d ",getpid(),getppid()); sleep(5); printf("Child: pid is %d and ppid is %d ",getpid(),getppid()); system("ps -f"); } else { printf("Parent: pid is %d and ppid is %d ",getpid(),getppid()); sleep(2); exit(0); } return 0; }
Compilation and Execution Steps
UID PID PPID C STIME TTY TIME CMD 4581875 180558 0 0 09:19 ? 00:00:00 sh -c cd /home/cg/root/4581875; timeout 10s main 4581875 180564 180558 0 09:19 ? 00:00:00 timeout 10s main 4581875 180565 180564 0 09:19 ? 00:00:00 main 4581875 180566 180565 0 09:19 ? 00:00:00 ps -f Parent: pid is 180565 and ppid is 180564 UID PID PPID C STIME TTY TIME CMD 4581875 180567 0 0 09:19 ? 00:00:00 main 4581875 180820 180567 0 09:19 ? 00:00:00 ps -f Child: pid is 180567 and ppid is 180565 Child: pid is 180567 and ppid is 0
Zombie Process
In simple terms, assume that you have two processes, namely the parent and the child process. It is the responsibipty of the parent process to wait for child process and then clean up the child process entry from the process table. What if the parent process is not ready to wait for the child process, and in the meantime the child process gets its job done and exits? Now, the child process would become the zombie process. Of course, the zombie process is cleaned up after the parent process becomes ready.
Let us understand this with the help of an example.
/* File Name: zombie_process.c */
#include<stdio.h> #include<stdpb.h> int main() { int pid; pid = fork(); if (pid == 0) { system("ps -f"); printf("Child: pid is %d and ppid is %d ",getpid(),getppid()); exit(0); } else { printf("Parent: pid is %d and ppid is %d ",getpid(),getppid()); sleep(10); system("ps aux|grep Z"); } return 0; }
Compilation and Execution Steps
UID PID PPID C STIME TTY TIME CMD 4581875 184946 0 0 09:20 ? 00:00:00 sh -c cd /home/cg/root/4581875; timeout 10s main 4581875 184952 184946 0 09:20 ? 00:00:00 timeout 10s main 4581875 184953 184952 0 09:20 ? 00:00:00 main 4581875 184954 184953 0 09:20 ? 00:00:00 main 4581875 184955 184954 0 09:20 ? 00:00:00 ps -f Child: pid is 184954 and ppid is 184953
Daemon Process
In simple terms, the process which doesn’t have any associated shell or terminal is known as the daemon process. Why this is needed? These are the processes which run in the background to perform actions at predefined intervals and also respond to certain events. The daemon process should not have any user interaction, since it runs as a background process.
The internal Linux daemon processes usually ends with the letter “d” such as Kernel Daemons (ksoftirqd, kblockd, kswapd, etc.), Printing Daemons (cupsd, lpd, etc.), File Service Daemons (smbd, nmbd, etc.), Administrative database daemons (ypbind, ypserv, etc.), Electronic Mail Daemons (sendmail, popd, smtpd, etc.), Remote Login and Command Execution Daemons (sshd, in.telnetd, etc.), Booting and Configuration Daemons (dhcpd, udevd, etc.), init process (init), cron daemon, atd daemon, etc.
Now let us see how to create a daemon process. Following are the steps −
Step 1 − Create a child process. Now we have two processes – the parent process and the child process
Usually the process hierarchy is SHELL → PARENT PROCESS → CHILD PROCESS
Step 2 − Terminate the parent process by exiting. The child process now becomes the orphan process and is taken over by init process.
Now, the hierarchy is INIT PROCESS → CHILD PROCESS
Step 3 − Calpng the setsid() system call creates a new session, if the calpng process is not a process group leader. Now the calpng process becomes the group leader of the new session. This process will be the only process in this new process group and in this new session.
Step 4 − Set the process group ID and session ID to PID of the calpng process.
Step 5 − Close the default file descriptors (standard input, standard output, and standard error) of the process as the terminal and shell are now disconnected from the apppcation.
/* Filename: daemon_test.c */
#include<stdio.h> #include<sys/types.h> #include<sys/stat.h> #include<unistd.h> #include<fcntl.h> #include<stdpb.h> #include<string.h> int main(int argc, char *argv[]) { pid_t pid; int counter; int fd; int max_iterations; char buffer[100]; if (argc < 2) max_iterations = 5; else { max_iterations = atoi(argv[1]); if ( (max_iterations <= 0) || (max_iterations > 20) ) max_iterations = 10; } pid = fork(); // Unable to create child process if (pid < 0) { perror("fork error "); exit(1); } // Child process if (pid == 0) { fd = open("/tmp/DAEMON.txt", O_WRONLY|O_CREAT|O_TRUNC, 0644); if (fd == -1) { perror("daemon txt file open error "); return 1; } printf("Child: pid is %d and ppid is %d ", getpid(), getppid()); printf(" Child process before becoming session leader "); sprintf(buffer, "ps -ef|grep %s", argv[0]); system(buffer); setsid(); printf(" Child process after becoming session leader "); sprintf(buffer, "ps -ef|grep %s", argv[0]); system(buffer); close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO); } else { printf("Parent: pid is %d and ppid is %d ", getpid(), getppid()); printf("Parent: Exiting "); exit(0); } // Executing max_iteration times for (counter = 0; counter < max_iterations; counter++) { sprintf(buffer, "Daemon process: pid is %d and ppid is %d ", getpid(), getppid()); write(fd, buffer, strlen(buffer)); sleep(2); } strcpy(buffer, "Done "); write(fd, buffer, strlen(buffer)); // Can t print this as file descriptors are already closed printf("DoneDone "); close(fd); return 0; }
Parent: pid is 193524 and ppid is 193523 Parent: Exiting 4581875 193525 0 0 09:23 ? 00:00:00 main 4581875 193526 193525 0 09:23 ? 00:00:00 sh -c ps -ef|grep main 4581875 193528 193526 0 09:23 ? 00:00:00 grep main 4581875 193525 0 0 09:23 ? 00:00:00 main 4581875 193529 193525 0 09:23 ? 00:00:00 sh -c ps -ef|grep main 4581875 193531 193529 0 09:23 ? 00:00:00 grep mainAdvertisements