Otros procesos
Hasta ahora, hemos discutido sobre los procesos, su creación, procesos padre e hijo, etc. La discusión estará incompleta sin discutir otros procesos relacionados, como el proceso Orphan, el proceso Zombie y el proceso Daemon.
Proceso huérfano
Como lo indica el nombre, huérfano implica proceso sin padres. Cuando ejecutamos un programa o aplicación, el proceso principal de la aplicación es shell. Cuando creamos un proceso usando fork (), el proceso recién creado es el proceso hijo y el proceso que creó al hijo es el proceso padre. A su vez, el proceso padre de esto es shell. Por supuesto, el padre de todos los procesos es init process (ID de proceso → 1).
Lo anterior es un escenario habitual, sin embargo, ¿qué sucede si el proceso padre sale antes que el proceso hijo? El resultado es que el proceso hijo ahora se convierte en el proceso huérfano. Entonces, ¿qué pasa con su padre, su nuevo padre es el padre de todos los procesos, que no es más que el proceso de inicio (ID de proceso - 1).
Intentemos entender esto usando el siguiente ejemplo.
/ * Nombre de archivo: 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;
}
Pasos de compilación y ejecución
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
Proceso Zombie
En términos simples, suponga que tiene dos procesos, a saber, el proceso principal y el secundario. Es responsabilidad del proceso padre esperar al proceso hijo y luego limpiar la entrada del proceso hijo de la tabla de procesos. ¿Qué sucede si el proceso padre no está listo para esperar al proceso hijo y, mientras tanto, el proceso hijo hace su trabajo y sale? Ahora, el proceso hijo se convertiría en el proceso zombi. Por supuesto, el proceso zombie se limpia una vez que el proceso principal está listo.
Entendamos esto con la ayuda de un ejemplo.
/ * Nombre de archivo: 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;
}
Pasos de compilación y ejecución
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
Proceso de demonio
En términos simples, el proceso que no tiene ningún shell o terminal asociado se conoce como proceso demonio. ¿Por qué esto es necesario? Estos son los procesos que se ejecutan en segundo plano para realizar acciones a intervalos predefinidos y también responder a ciertos eventos. El proceso del demonio no debería tener ninguna interacción del usuario, ya que se ejecuta como un proceso en segundo plano.
Los procesos internos del demonio de Linux generalmente terminan con la letra "d", como Kernel Daemons (ksoftirqd, kblockd, kswapd, etc.), Printing Daemons (cupsd, lpd, etc.), File Service Daemons (smbd, nmbd, etc.) , Demonios de bases de datos administrativas (ypbind, ypserv, etc.), demonios de correo electrónico (sendmail, popd, smtpd, etc.), demonios de inicio de sesión remoto y ejecución de comandos (sshd, in.telnetd, etc.), demonios de arranque y configuración (dhcpd , udevd, etc.), proceso de inicio (init), demonio cron, demonio atd, etc.
Ahora veamos cómo crear un proceso de demonio. Los siguientes son los pasos:
Step 1- Crear un proceso hijo. Ahora tenemos dos procesos: el proceso padre y el proceso hijo
Por lo general, la jerarquía del proceso es SHELL → PROCESO DE LOS PADRES → PROCESO DEL NIÑO
Step 2- Termine el proceso principal saliendo. El proceso hijo ahora se convierte en el proceso huérfano y es asumido por el proceso init.
Ahora, la jerarquía es PROCESO INICIAL → PROCESO INFANTIL
Step 3- La llamada al sistema setsid () crea una nueva sesión, si el proceso que llama no es un líder de grupo de procesos. Ahora el proceso de llamada se convierte en el líder de grupo de la nueva sesión. Este proceso será el único proceso en este nuevo grupo de procesos y en esta nueva sesión.
Step 4 - Configure el ID del grupo de procesos y el ID de la sesión en el PID del proceso de llamada.
Step 5 - Cierre los descriptores de archivo predeterminados (entrada estándar, salida estándar y error estándar) del proceso, ya que el terminal y el shell ahora están desconectados de la aplicación.
/ * Nombre de archivo: 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