Sistema de bifurcación llamada Linux

Fork System Call Linux



La llamada al sistema fork se utiliza para crear nuevos procesos. El proceso recién creado es el proceso hijo. El proceso que llama a fork y crea un nuevo proceso es el proceso padre. Los procesos hijo y padre se ejecutan al mismo tiempo.

Pero los procesos hijo y padre residen en diferentes espacios de memoria. Estos espacios de memoria tienen el mismo contenido y cualquier operación realizada por un proceso no afectará al otro proceso.







Cuando se crea el proceso hijo; ahora ambos procesos tendrán el mismo contador de programa (PC), por lo que ambos procesos apuntarán a la misma instrucción siguiente. Los archivos abiertos por el proceso padre serán los mismos para el proceso hijo.



El proceso hijo es exactamente el mismo que el padre, pero hay diferencias en los ID de los procesos:



  1. El ID de proceso del proceso hijo es un ID de proceso único que es diferente de los ID de todos los demás procesos existentes.
  2. El ID de proceso principal será el mismo que el ID de proceso del padre del niño.

Propiedades del proceso hijo

Las siguientes son algunas de las propiedades que tiene un proceso hijo:





  1. Los contadores de CPU y la utilización de recursos se inicializan para restablecerse a cero.
  2. Cuando se termina el proceso padre, los procesos hijo no reciben ninguna señal porque el atributo PR_SET_PDEATHSIG en prctl () se restablece.
  3. El hilo usado para llamar a fork () crea el proceso hijo. Entonces, la dirección del proceso hijo será la misma que la del padre.
  4. El proceso hijo hereda el descriptor de archivo del proceso principal. Por ejemplo, el desplazamiento del archivo o el estado de las banderas y los atributos de E / S se compartirán entre los descriptores de archivo de los procesos padre e hijo. Por lo tanto, el descriptor de archivo de la clase principal se referirá al mismo descriptor de archivo de la clase secundaria.
  5. Los descriptores de cola de mensajes abiertos del proceso padre son heredados por el proceso hijo. Por ejemplo, si un descriptor de archivo contiene un mensaje en el proceso padre, el mismo mensaje estará presente en el descriptor de archivo correspondiente del proceso hijo. Entonces podemos decir que los valores de las banderas de estos descriptores de archivos son los mismos.
  6. De manera similar, los procesos secundarios heredarán los flujos de directorio abiertos.
  7. El valor de holgura del temporizador predeterminado de la clase secundaria es el mismo que el valor de holgura del temporizador actual de la clase principal.

Propiedades que no hereda el proceso hijo

Las siguientes son algunas de las propiedades que no hereda un proceso hijo:

  1. Bloqueos de memoria
  2. La señal pendiente de una clase secundaria está vacía.
  3. Procesar bloqueos de registros asociados (fcntl ())
  4. Operaciones de E / S asincrónicas y contenido de E / S.
  5. Notificaciones de cambio de directorio.
  6. Los temporizadores como alarm (), setitimer () no son heredados por la clase secundaria.

tenedor () en C

No hay argumentos en fork () y el tipo de retorno de fork () es entero. Debe incluir los siguientes archivos de encabezado cuando se usa fork ():



#incluir
#incluir
#incluir

Cuando se trabaja con fork (), se puede utilizar para type pid_t para ID de procesos como pid_t se define en.

El archivo de encabezado es donde se define fork (), por lo que debe incluirlo en su programa para usar fork ().

El tipo de retorno se define en y la llamada a fork () se define en. Por lo tanto, debe incluir ambos en su programa para usar la llamada al sistema fork ().

Sintaxis de fork ()

La sintaxis de la llamada al sistema fork () en Linux, Ubuntu es la siguiente:

pid_t fork (vacío);

En la sintaxis, el tipo de retorno es pid_t . Cuando el proceso hijo se crea con éxito, el PID del proceso hijo se devuelve en el proceso padre y se devolverá 0 al proceso hijo en sí.

Si hay algún error, se devuelve -1 al proceso padre y no se crea el proceso hijo.

|_+_|

Ejemplo 1: llamar a fork ()

Considere el siguiente ejemplo en el que hemos utilizado la llamada al sistema fork () para crear un nuevo proceso hijo:

CÓDIGO:

#incluir
#incluir
#incluir

En tprincipal()
{
tenedor();
printf ('Usando la llamada al sistema fork () orte');
regreso 0;
}

PRODUCCIÓN:

Usando la llamada al sistema fork ()
Usando la llamada al sistema fork ()

En este programa, hemos utilizado fork (), esto creará un nuevo proceso hijo. Cuando se crea el proceso hijo, tanto el proceso padre como el proceso hijo apuntarán a la siguiente instrucción (el mismo contador de programa). De esta forma, las instrucciones restantes o sentencias C se ejecutarán el número total de tiempos de proceso, es decir 2norteveces, donde n es el número de llamadas al sistema fork ().

Entonces, cuando la llamada fork () se usa una vez como arriba (21= 2) tendremos nuestra salida 2 veces.

Aquí, cuando se usa la llamada al sistema fork (), la estructura interna se verá así:

Considere el siguiente caso en el que el fork () se usa 4 veces:

CÓDIGO:

#incluir
#incluir
#incluir

En tprincipal()
{
tenedor();
tenedor();
tenedor();
tenedor();
printf ('Usando la llamada al sistema fork ()');
regreso 0;
}

Producción:

|_+_|

Ahora el número total de procesos creados son 24= 16 y tenemos nuestra declaración de impresión ejecutada 16 veces.

Ejemplo 2: probar si fork () fue exitoso

En el siguiente ejemplo, usamos la construcción de toma de decisiones para probar el valor (int) devuelto por fork (). Y se muestran los mensajes correspondientes:

CÓDIGO:

#incluir
#incluir
#incluir

En tprincipal()
{
pid_t p;
pag=tenedor();
si(pag==-1)
{
printf ('Hay un error al llamar a fork ()');
}
si(pag==0)
{
printf ('Estamos en el proceso del niño');
}
demás
{
printf ('Estamos en el proceso de padres');
}
regreso 0;
}

PRODUCCIÓN:

Estamos en proceso de padres
Estamos en el proceso del niño

En el ejemplo anterior hemos utilizado el tipo pid_t que almacenará el valor de retorno de fork (). fork () se llama en línea:

pag=tenedor();

Entonces, el valor entero devuelto por fork () se almacena en py luego se compara p para verificar si nuestra llamada a fork () fue exitosa.

Cuando se utiliza la llamada fork () y el hijo se crea correctamente, la identificación del proceso hijo se devolverá al proceso principal y se devolverá 0 al proceso hijo. La ID del proceso hijo en el proceso padre no será la misma que la ID del proceso hijo en el propio proceso hijo. En el proceso hijo, el ID del proceso hijo será 0.

Con este tutorial puede ver cómo comenzar con la llamada al sistema fork en linux.