Autres processus
Jusqu'à présent, nous avons discuté des processus, de sa création, des processus parents et enfants, etc. La discussion sera incomplète sans discuter d'autres processus connexes, tels que le processus orphelin, le processus Zombie et le processus Démon.
Processus orphelin
Comme indiqué par le nom, orphelin implique un processus sans parent. Lorsque nous exécutons un programme ou une application, le processus parent de l'application est shell. Lorsque nous créons un processus à l'aide de fork (), le processus nouvellement créé est le processus enfant et le processus qui a créé l'enfant est le processus parent. À son tour, le processus parent de ceci est shell. Bien sûr, le parent de tous les processus est init process (Process ID → 1).
Ce qui précède est un scénario habituel, cependant, que se passe-t-il si le processus parent se termine avant le processus enfant. Le résultat est que le processus enfant devient maintenant le processus orphelin. Alors qu'en est-il de son parent, son nouveau parent est le parent de tous les processus, qui n'est rien d'autre qu'un processus init (Process ID - 1).
Essayons de comprendre cela en utilisant l'exemple suivant.
/ * Nom du fichier: orphan_process.c * /
#include<stdio.h>
#include<stdlib.h>
int main() {
int pid;
system("ps -f");
pid = fork();
if (pid == 0) {
printf("Child: pid is %d and ppid is %d\n",getpid(),getppid());
sleep(5);
printf("Child: pid is %d and ppid is %d\n",getpid(),getppid());
system("ps -f");
} else {
printf("Parent: pid is %d and ppid is %d\n",getpid(),getppid());
sleep(2);
exit(0);
}
return 0;
}
Étapes de compilation et d'exécution
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
Processus de zombie
En termes simples, supposons que vous ayez deux processus, à savoir le processus parent et le processus enfant. Il est de la responsabilité du processus parent d'attendre le processus enfant, puis de nettoyer l'entrée de processus enfant de la table de processus. Que se passe-t-il si le processus parent n'est pas prêt à attendre le processus enfant et que, entre-temps, le processus enfant termine son travail et se termine? Désormais, le processus enfant deviendrait le processus zombie. Bien sûr, le processus zombie est nettoyé une fois que le processus parent est prêt.
Comprenons cela à l'aide d'un exemple.
/ * Nom du fichier: zombie_process.c * /
#include<stdio.h>
#include<stdlib.h>
int main() {
int pid;
pid = fork();
if (pid == 0) {
system("ps -f");
printf("Child: pid is %d and ppid is %d\n",getpid(),getppid());
exit(0);
} else {
printf("Parent: pid is %d and ppid is %d\n",getpid(),getppid());
sleep(10);
system("ps aux|grep Z");
}
return 0;
}
Étapes de compilation et d'exécution
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
Processus démon
En termes simples, le processus qui n'a pas de shell ou de terminal associé est connu sous le nom de processus démon. Pourquoi est-ce nécessaire? Ce sont les processus qui s'exécutent en arrière-plan pour effectuer des actions à des intervalles prédéfinis et également répondre à certains événements. Le processus démon ne doit pas avoir d'interaction avec l'utilisateur, car il s'exécute en tant que processus d'arrière-plan.
Les processus de démon Linux internes se terminent généralement par la lettre «d» tels que les démons du noyau (ksoftirqd, kblockd, kswapd, etc.), les démons d'impression (cupsd, lpd, etc.), les démons de service de fichiers (smbd, nmbd, etc.) , Démons de base de données administrative (ypbind, ypserv, etc.), Démons de courrier électronique (sendmail, popd, smtpd, etc.), Démons de connexion à distance et d'exécution de commande (sshd, in.telnetd, etc.), Démons de démarrage et de configuration (dhcpd , udevd, etc.), processus init (init), démon cron, démon atd, etc.
Voyons maintenant comment créer un processus démon. Voici les étapes -
Step 1- Créez un processus enfant. Nous avons maintenant deux processus - le processus parent et le processus enfant
Habituellement, la hiérarchie des processus est SHELL → PARENT PROCESS → CHILD PROCESS
Step 2- Terminez le processus parent en quittant. Le processus enfant devient maintenant le processus orphelin et est repris par le processus init.
Maintenant, la hiérarchie est INIT PROCESS → CHILD PROCESS
Step 3- L'appel de l'appel système setsid () crée une nouvelle session, si le processus appelant n'est pas un chef de groupe de processus. Maintenant, le processus d'appel devient le chef de groupe de la nouvelle session. Ce processus sera le seul processus dans ce nouveau groupe de processus et dans cette nouvelle session.
Step 4 - Définissez l'ID de groupe de processus et l'ID de session sur PID du processus appelant.
Step 5 - Fermez les descripteurs de fichier par défaut (entrée standard, sortie standard et erreur standard) du processus car le terminal et le shell sont maintenant déconnectés de l'application.
/ * Nom de fichier: daemon_test.c * /
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<fcntl.h>
#include<stdlib.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\n");
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\n");
return 1;
}
printf("Child: pid is %d and ppid is %d\n", getpid(), getppid());
printf("\nChild process before becoming session leader\n");
sprintf(buffer, "ps -ef|grep %s", argv[0]);
system(buffer);
setsid();
printf("\nChild process after becoming session leader\n");
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\n", getpid(), getppid());
printf("Parent: Exiting\n");
exit(0);
}
// Executing max_iteration times
for (counter = 0; counter < max_iterations; counter++) {
sprintf(buffer, "Daemon process: pid is %d and ppid is %d\n", getpid(), getppid());
write(fd, buffer, strlen(buffer));
sleep(2);
}
strcpy(buffer, "Done\n");
write(fd, buffer, strlen(buffer));
// Can't print this as file descriptors are already closed
printf("DoneDone\n");
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 main