Llamada del sistema de Linux Exec

Llamada del sistema de Linux Exec
La llamada del sistema EXEC se utiliza para ejecutar un archivo que reside en un proceso activo. Cuando se llama a Exec, se reemplaza el archivo ejecutable anterior y se ejecuta un nuevo archivo.

Más precisamente, podemos decir que el uso de la llamada del sistema EXEC reemplazará el archivo o el programa anterior del proceso con un nuevo archivo o programa. Todo el contenido del proceso se reemplaza con un nuevo programa.

El segmento de datos del usuario que ejecuta la llamada al sistema Exec () se reemplaza con el archivo de datos cuyo nombre se proporciona en el argumento mientras llama a Exec ().

El nuevo programa se carga en el mismo espacio de proceso. El proceso actual se convierte en un nuevo proceso y, por lo tanto, el PID de ID del proceso no se cambia, esto se debe a que no estamos creando un nuevo proceso, solo estamos reemplazando un proceso con otro proceso en ejecutivo.

Si el proceso de ejecución actualmente contiene más de un hilo, todos los subprocesos se terminarán y se cargará la nueva imagen del proceso y luego se ejecutará. No hay funciones de destructor que terminen los hilos del proceso actual.

El PID del proceso no se cambia, pero los datos, el código, la pila, el montón, etc. del proceso se cambian y se reemplazan con los del proceso recién cargado. El nuevo proceso se ejecuta desde el punto de entrada.

Exec System Call es una colección de funciones y en el lenguaje de programación C, los nombres estándar para estas funciones son los siguientes:

  1. execl
  2. ejecución
  3. execlp
  4. execv
  5. ejecutar
  6. execVP


Cabe señalar aquí que estas funciones tienen la misma base ejecución seguido de una o más letras. Estos se explican a continuación:

mi: Es una variedad de punteros que apunta a las variables de entorno y se pasa explícitamente al proceso recién cargado.

L: l es para los argumentos de la línea de comando pasó una lista a la función

pag: P es la variable de entorno de ruta que ayuda a encontrar el archivo aprobado como un argumento para cargarse en el proceso.

V: V es para los argumentos de la línea de comando. Estos se pasan como una variedad de punteros a la función.

Por qué se usa ejecutor?

EEX se utiliza cuando el usuario desea iniciar un nuevo archivo o programa en el mismo proceso.

Trabajo interno de ejecutivo

Considere los siguientes puntos para comprender el funcionamiento de Exec:

  1. La imagen del proceso actual se sobrescribe con una nueva imagen de proceso.
  2. La nueva imagen del proceso es la que pasó como argumento exec
  3. El proceso de ejecución actualmente está finalizado
  4. La nueva imagen de proceso tiene la misma ID de proceso, el mismo entorno y el mismo descriptor de archivos (porque el proceso no se reemplaza la imagen del proceso se reemplaza)
  5. La estadística de la CPU y la memoria virtual se ven afectadas. La asignación de memoria virtual de la imagen del proceso actual se reemplaza por la memoria virtual de la nueva imagen de proceso.

Sintaxis de funciones familiares exec:

Las siguientes son las sintaxis para cada función de Exec:

int execl (const char* ruta, const char* arg, ...)
int execlp (const char* file, const char* arg, ...)
int execle (const char* ruta, const char* arg, ..., char* const envp [])
int execv (const char* ruta, const char* argv [])
int execvp (const char* file, const char* argv [])
int execvpe (const char* file, const char* argv [], char* const envp [])

Descripción:

El tipo de retorno de estas funciones es int. Cuando la imagen del proceso se reemplaza correctamente, nada se devuelve a la función de llamadas porque el proceso que la llama ya no se ejecuta. Pero si hay algún error, se devolverá -1. Si se produce algún error, un errar Está establecido.

En la sintaxis:

  1. camino se usa para especificar el nombre de ruta completo del archivo que se ejecuta.
  1. argumento ¿Se pasa el argumento?. En realidad, es el nombre del archivo que se ejecutará en el proceso. La mayoría de las veces el valor de arg y ruta es el mismo.
  1. const char* arg en funciones execl (), execlp () y execle () se considera arg0, arg1, arg2, ..., argn. Básicamente es una lista de punteros para cuerdas terminadas. Aquí el primer argumento apunta al nombre de archivo que se ejecutará como se describe en el punto 2.
  1. envidiar es una matriz que contiene punteros que apuntan a las variables de entorno.
  1. archivo se utiliza para especificar el nombre de ruta que identificará la ruta del nuevo archivo de imagen de proceso.
  1. Las funciones de ejecutivo llaman a ese final con mi se utilizan para cambiar el entorno para la nueva imagen de proceso. Estas funciones pasan la lista de configuración del entorno utilizando el argumento envidiar. Este argumento es una matriz de caracteres que apunta a una cadena nula terminada y define la variable de entorno.

Para usar las funciones de la familia EXEC, debe incluir el siguiente archivo de encabezado en su programa C:

#incluir

Ejemplo 1: Uso de la llamada del sistema EXEC en el programa C

Considere el siguiente ejemplo en el que hemos utilizado la llamada del sistema EXEC en la programación C en Linux, Ubuntu: tenemos dos archivos C aquí.C y hola.C:

ejemplo.C

CÓDIGO:

#incluir
#incluir
#incluir
int main (int argc, char *argv [])

printf ("PID de ejemplo.c = %d \ n ", getpid ());
char *args [] = "hola", "c", "programación", nulo;
execv ("./hola ", args);
printf ("Volver al ejemplo.C");
regresar 0;

Hola.C

CÓDIGO:

#incluir
#incluir
#incluir
int main (int argc, char *argv [])

printf ("Estamos en hola.c \ n ");
printf ("Pid de Hello.c = %d \ n ", getpid ());
regresar 0;

PRODUCCIÓN:

Pid de ejemplo.C = 4733
Estamos en hola.C
Pid de hola.C = 4733

En el ejemplo anterior tenemos un ejemplo.archivo c y hola.archivo c. En el ejemplo .Cile C En primer lugar, hemos imprimido la ID del proceso actual (ejemplo de archivo.C se está ejecutando en el proceso actual). Luego, en la siguiente línea, hemos creado una variedad de punteros de personajes. El último elemento de esta matriz debe ser nulo como punto de terminación.

Luego hemos usado la función execv () que toma el nombre del archivo y la matriz de puntero de caracteres como argumento. Cabe señalar aquí que hemos usado ./ Con el nombre del archivo, especifica la ruta del archivo. Como el archivo está en la carpeta donde el ejemplo.C reside, por lo que no es necesario especificar la ruta completa.

Cuando se llama a la función execv (), nuestra imagen de proceso se reemplazará ahora el ejemplo del archivo.C no está en el proceso pero el archivo hola.C está en el proceso. Se puede ver que la identificación del proceso es la misma si hola.c es imagen o ejemplo de proceso.c es la imagen del proceso porque el proceso es el mismo y la imagen del proceso solo se reemplaza.

Luego tenemos otra cosa que tener en cuenta aquí, que es la instrucción printf () después de que execv () no se ejecute. Esto se debe a que el control nunca se devuelve a la imagen de proceso anterior una vez que la imagen de proceso nueva lo reemplaza. El control solo vuelve a la función de llamadas al reemplazar la imagen del proceso no tiene éxito. (El valor de retorno es -1 en este caso).

Diferencia entre las llamadas del sistema Fork () y Exec ():

La llamada del sistema Fork () se usa para crear una copia exacta de un proceso en ejecución y la copia creada es el proceso del niño y el proceso de ejecución es el proceso principal. Mientras que, la llamada al sistema exec () se utiliza para reemplazar una imagen de proceso con una nueva imagen de proceso. Por lo tanto, no hay un concepto de procesos de padres e hijos en la llamada del sistema exec ().

En el sistema Fork (), la llamada de los procesos de los padres e hijos se ejecutan al mismo tiempo. Pero en la llamada del sistema EXEC (), si el reemplazo de la imagen del proceso es exitosa, el control no vuelve a donde se llamó la función EXEC en lugar de ejecutar el nuevo proceso. El control solo se transferirá de nuevo si hay algún error.

Ejemplo 2: Combinación de llamadas del sistema Fork () y Exec ()

Considere el siguiente ejemplo en el que hemos usado las llamadas del sistema Fork () y Exec () en el mismo programa:

ejemplo.C

CÓDIGO:

#incluir
#incluir
#incluir
int main (int argc, char *argv [])

printf ("PID de ejemplo.c = %d \ n ", getpid ());
pid_t p;
p = bifurcado ();
if (p ==-1)

printf ("Hay un error al llamar a la fork ()");

if (p == 0)

printf ("Estamos en el proceso infantil \ n");
printf ("Llamando hola.c del proceso infantil \ n ");
char *args [] = "hola", "c", "programación", nulo;
execv ("./hola ", args);

demás

printf ("Estamos en el proceso principal");

regresar 0;

Hola.C:

CÓDIGO:

#incluir
#incluir
#incluir
int main (int argc, char *argv [])

printf ("Estamos en hola.c \ n ");
printf ("Pid de Hello.c = %d \ n ", getpid ());
regresar 0;

PRODUCCIÓN:

Pid de ejemplo.C = 4790
Estamos en el proceso de los padres
Estamos en el proceso infantil
Llamando hola.C del proceso infantil
Estamos en hola.C
Pid de hola.C = 4791

En este ejemplo hemos usado la llamada del sistema Fork (). Cuando se cree el proceso infantil, se asignará 0 a P y luego nos moveremos al proceso infantil. Ahora se ejecutará el bloque de declaraciones con if (p == 0). Se muestra un mensaje y hemos usado la llamada del sistema ExecV () y la imagen actual del proceso infantil que es ejemplo.C se reemplazará con hola.C. Antes de que execv () llame a los procesos de hijos y padres fuera los mismos.

Se puede ver que el PID de ejemplo.C y hola.C es diferente ahora. Esto es porque el ejemplo.C es la imagen del proceso principal y hola.C es la imagen del proceso infantil.