GNU/Linux >> Tutoriales Linux >  >> Linux

Procesos UNIX/Linux:Función C fork()

Cada instancia en ejecución de un programa se conoce como un proceso. El concepto de procesos es fundamental para los sistemas operativos UNIX/Linux. Un proceso tiene su propia identidad en forma de PID o ID de proceso. Este PID para cada proceso es único en todo el sistema operativo. Además, cada proceso tiene su propio espacio de direcciones de proceso donde se colocan segmentos de memoria como segmento de código, segmento de datos, segmento de pila, etc. El concepto de proceso es muy amplio y puede clasificarse ampliamente en creación de procesos, ejecución de procesos y terminación de procesos.

Serie de procesos de Linux:parte 1, parte 2, parte 3, parte 4 (este artículo).

En este artículo nos concentraremos en el aspecto de creación de procesos desde el punto de vista de la programación. Nos centraremos en la función fork() y entenderemos cómo funciona.

La función bifurcación()

La función fork() se utiliza para crear un nuevo proceso duplicando el proceso existente desde el que se llama. El proceso existente desde el que se llama a esta función se convierte en el proceso principal y el proceso recién creado se convierte en el proceso secundario. Como ya se indicó, el niño es una copia duplicada del padre, pero hay algunas excepciones.

  • El niño tiene un PID único como cualquier otro proceso que se ejecuta en el sistema operativo.
  • El hijo tiene un ID de proceso principal que es el mismo que el PID del proceso que lo creó.
  • La utilización de recursos y los contadores de tiempo de CPU se restablecen a cero en el proceso secundario.
  • El conjunto de señales pendientes en child está vacío.
  • El niño no hereda ningún temporizador de su padre

Tenga en cuenta que la lista anterior no es exhaustiva. Hay un montón de puntos mencionados en la página de manual de fork(). Recomiendo encarecidamente a los lectores de este artículo que revisen esos puntos en la página de manual de la función fork().

El tipo de retorno

Fork() tiene un comportamiento interesante al volver al método de llamada. Si la función fork() tiene éxito, regresa dos veces. Una vez que regresa en el proceso secundario con el valor de retorno '0' y luego regresa en el proceso principal con el PID del niño como valor de retorno. Este comportamiento se debe al hecho de que una vez que se llama a la bifurcación, se crea el proceso secundario y dado que el proceso secundario comparte el segmento de texto con el proceso principal y continúa la ejecución desde la siguiente declaración en el mismo segmento de texto, por lo que la bifurcación regresa dos veces (una vez en el proceso principal). y una vez en niño).

Ejemplo de horquilla C

Tomemos un ejemplo para ilustrar el uso de la función de horquilla.

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

int var_glb; /* A global variable*/

int main(void)
{
    pid_t childPID;
    int var_lcl = 0;

    childPID = fork();

    if(childPID >= 0) // fork was successful
    {
        if(childPID == 0) // child process
        {
            var_lcl++;
            var_glb++;
            printf("\n Child Process :: var_lcl = [%d], var_glb[%d]\n", var_lcl, var_glb);
        }
        else //Parent process
        {
            var_lcl = 10;
            var_glb = 20;
            printf("\n Parent process :: var_lcl = [%d], var_glb[%d]\n", var_lcl, var_glb);
        }
    }
    else // fork failed
    {
        printf("\n Fork failed, quitting!!!!!!\n");
        return 1;
    }

    return 0;
}

En el código de arriba:

  • Una variable local y una global (var_lcl y var_glb) declaradas e inicializadas con el valor '0'
  • Luego se llama a la función fork() y su valor de retorno se guarda en la variable childPID.
  • Ahora, se comprueba el valor de childPID para asegurarse de que se haya superado la función fork().
  • Luego, sobre la base del valor de childPID, se ejecuta el código para padre e hijo.
  • Una cosa a tener en cuenta aquí es ¿por qué se usan las variables var_lcl y var_glb?
  • Se utilizan para mostrar que tanto el proceso secundario como el primario funcionan en copias separadas de estas variables.
  • Se utilizan valores separados de estas variables para mostrar el hecho mencionado anteriormente.
  • En Linux, se usa un mecanismo de copia en escritura en el que tanto el hijo como el padre siguen trabajando en la misma copia de la variable hasta que uno de ellos intenta cambiar su valor.
  • Después de la bifurcación, si el hijo se ejecutará primero o el padre depende del programador.

Ahora, cuando el código anterior se compila y ejecuta:

$ ./fork

Parent process :: var_lcl = [10], var_glb[20]

Child Process :: var_lcl = [1], var_glb[1]

Vemos que en el resultado anterior, tanto el proceso secundario como el principal se ejecutaron y los registros muestran valores separados de var_lcl y var_glb. Esto concluye que tanto el padre como el hijo tenían su propia copia de var_lcl y var_glb.

NOTA:Se puede usar una función getpid() para obtener el ID de proceso del proceso que llama y la función getppid() se puede usar para obtener el PID del proceso principal.


Linux
  1. 30 ejercicios de procesos de Linux para administradores de sistemas

  2. Linux – Proceso de inicio:¿ancestro de todos los procesos?

  3. Gestión de procesos en Ubuntu Linux

  4. ¿Cómo encontrar todos los procesos secundarios?

  5. Reintento de la bifurcación Linux ssh bash:no hay procesos secundarios

Cómo matar procesos Zombie en Linux

Supervisión de procesos en Linux

Linux frente a Unix

Comandos para la Gestión de Procesos en Linux

Cómo enviar procesos a segundo plano en Linux

Procesos de Linux:diseño de memoria, salida y funciones C _exit