Fork, exec, wait y exit system call explicados en Linux

Fork, exec, wait y exit system call explicados en Linux

 

La secuencia de instrucciones y datos que se pueden ejecutar una sola vez, varias veces o simultáneamente se denominan programas. Y el proceso es la ejecución de dichos programas. Entonces esos procesos pueden ejecutar muchos programas. En el mismo proceso, el sistema operativo puede cargar diferentes programas. Los nuevos programas heredan los estados de proceso reutilizados como directorios actuales, privilegios, identificadores de archivos, etc. Estas cosas se hacen al mismo nivel que las llamadas al sistema como fork(), exec(), wait() y exit().

En este artículo, vamos a discutir las llamadas al sistema de Linux fork(), exec(), wait() y exit() en detalle con ejemplos y casos de uso.

tenedor()

El fork() es una de las llamadas al sistema que es muy especial y útil en los sistemas Linux/Unix. Los procesos lo utilizan para crear los procesos que son copias de sí mismos. Con la ayuda de dichas llamadas al sistema, el proceso principal puede crear el proceso secundario. Hasta que el proceso secundario se ejecute por completo, el proceso principal se suspende.

Algunos de los puntos importantes en fork() son los siguientes.

  • El padre obtendrá el ID del proceso hijo con un valor distinto de cero.
  • Valor cero se devuelve al niño.
  • Si hay algún error de sistema o de hardware mientras se crea el hijo, se devuelve -1 a la bifurcación().
  • Con el ID de proceso único obtenido por el proceso secundario, no coincide con el ID de ningún grupo de procesos existente.

Para elaborar sobre el fork(), tomemos un ejemplo que aclara el concepto fork().

$ sudo vim fork.c

Fork exec wait y exit system call explicados en Linux

Aquí está el código para copiar/pegar:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>

int main(int argc, char **argv)
{
pid_t pid;
pid = fork();
if(pid==0)
{
printf("It is the child process and pid is %d\n",getpid());
exit(0);
}
else if(pid > 0)
{
printf("It is the parent process and pid is %d\n",getpid());
}
else
{
printf("Error while forking\n");
exit(EXIT_FAILURE);
}
return 0;
}

Producción:

$make fork

Fork exec wait y exit system call explicados en Linux

Y al ejecutar el script, obtenemos el resultado como se muestra a continuación.

$ ./fork

Fork exec wait y exit system call explicados en Linux

exec()

El exec() es una llamada al sistema que se ejecuta al reemplazar la imagen del proceso actual con la nueva imagen del proceso. Sin embargo, el proceso original permanece como un nuevo proceso, pero el nuevo proceso reemplaza los datos principales, los datos de la pila, etc. Ejecuta el programa desde el punto de entrada al cargar el programa en el espacio de proceso actual.

Para elaborar más, tomemos un ejemplo como se muestra a continuación.

 

$ sudo vim exec.c

Fork exec wait y exit system call explicados en Linux

Y aquí está el código:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>

main(void) {
  pid_t pid = 0;
  int status;
  pid = fork();

if (pid == 0) {
  printf("I am the child.");
  execl("/bin/ls", "ls", "-l", "/home/ubuntu/", (char *) 0);
  perror("In exec(): ");
}

if (pid > 0) {
  printf("I am the parent, and the child is %d.\n", pid);
  pid = wait(&status);
  printf("End of process %d: ", pid);

  if (WIFEXITED(status)) {
    printf("The process ended with exit(%d).\n", WEXITSTATUS(status));
  }

  if (WIFSIGNALED(status)) {
    printf("The process ended with kill -%d.\n", WTERMSIG(status));
  }
}

if (pid < 0) {
  perror("In fork():");
}

exit(0);
}

Producción:

$ make exec

Fork exec wait y exit system call explicados en Linux

Y al ejecutar el script, obtenemos el resultado como se muestra a continuación.

$ ./exec

Fork exec wait y exit system call explicados en Linux

wait()

Como en el caso de una bifurcación, los procesos secundarios se crean y se ejecutan, pero el proceso principal se suspende hasta que se ejecuta el proceso secundario. En este caso, una llamada al sistema wait() se activa automáticamente debido a la suspensión del proceso padre. Después de que el proceso secundario termina la ejecución, el proceso principal recupera el control nuevamente.

Para dar más detalles sobre wait(), tomemos un ejemplo que aclara la llamada al sistema wait().

$ sudo vim wait.c

Fork exec wait y exit system call explicados en Linux

Un aquí es el ejemplo de código:

#include<stdio.h> // printf()
#include<stdlib.h> // exit()
#include<sys/types.h> // pid_t
#include<sys/wait.h> // wait()
#include<unistd.h> // fork

int main(int argc, char **argv)
{

pid_t pid;
pid = fork();

if(pid==0)

{
printf("It is the child process and pid is %d\n",getpid());

int i=0;
for(i=0;i<8;i++)
{
printf("%d\n",i);
}

exit(0);

}
else if(pid > 0)
{

printf("It is the parent process and pid is %d\n",getpid());

int status;
wait(&status);
printf("Child is reaped\n");
}

else
{

printf("Error in forking..\n");
exit(EXIT_FAILURE);

}

return 0;

}

Producción:

$ make wait

Fork exec wait y exit system call explicados en Linux

Y al ejecutar el script, obtenemos el resultado como se muestra a continuación.

$ ./wait

Fork exec wait y exit system call explicados en Linux

exit()

exit() es una función de este tipo o una de las llamadas al sistema que se utiliza para terminar el proceso. Esta llamada al sistema define que la ejecución del subproceso se completa, especialmente en el caso de un entorno de subprocesos múltiples. Para referencia futura, se captura el estado del proceso.

Después del uso de la llamada al sistema exit(), el sistema operativo recupera todos los recursos utilizados en el proceso y luego finaliza el proceso. La llamada al sistema Exit() es equivalente a exit().

Sinopsis

#include <unistd.h>
void _exit(int status);
#include <stdlib.h>
void _Exit(int status);

Puede ver el uso de la función exit() en los ejemplos anteriores de fork(), wait(). El uso de la llamada al sistema exit() se realiza para finalizar el proceso.

Conclusión

En este artículo, aprendimos las llamadas al sistema fork(), exec(), wait() y exit() en detalle con algunos ejemplos. Para obtener más detalles, intente ejecutar los programas utilizando esas llamadas al sistema y vea el resultado. ¡Gracias!

Deja un comentario

Tu dirección de correo electrónico no será publicada.

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.