gestión de procesos experimentales

creación de procesos de experimentos

1. Propósito del experimento

  1. Profundizar la comprensión del concepto de proceso y comprender mejor la esencia de la ejecución concurrente
  2. Domina las operaciones de creación y terminación de procesos del sistema operativo Linux
  3. Domina la operación de crear un proceso hijo y cargar una nueva imagen en el sistema Linux.

2. Contenido del experimento
(1) Escriba un programa en C y use la bifurcación de llamada al sistema() para crear un proceso hijo. Requisitos: ① En el proceso secundario, genere la indicación de que el proceso actual es un proceso secundario, el PID del proceso actual y el PID del proceso principal, determine el valor de retorno del proceso actual de acuerdo con la entrada del usuario y las indicaciones de salida . ②En el proceso principal, salida: la solicitud de que el proceso actual es el proceso principal, el PID del proceso actual y el PID del proceso secundario, el valor de retorno obtenido después de esperar a que finalice el proceso secundario y la solicitud de salida.
(2) Escriba un programa en C, use la llamada al sistema fork() para crear un proceso secundario, y el proceso secundario llama a la función de la familia exec para ejecutar el comando del sistema ls.

3. Pasos experimentales

1. El primer proceso de escritura del experimento, use vim para editar el código y luego ejecute

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

int main(){
    
    

        pid_t childpid; /*variable to store the child's pid*/
        int retval;    /*user-provided return code for child process*/
        int status;    /*child's exit status for parent process*/

        /*create new process*/
        childpid = fork()
        if (childpid >= 0) {
    
    
                if (childpid == 0) {
    
    
                        printf("Child:I am the child process\n");
                        printf("Child:My PID is %d\n",getpid());
                        printf("Child:My parent's PID is %d\n",getppid());
                        printf("Child:The value of fork return is %d\n",childpid);
                        printf("Child:Sleep for one second...\n");
                        sleep(1);
                        printf("Child:Enter an exit value (0~255): ");
                        scanf("%d",&retval);
                        printf("Child:Goodbye! \n");
                        exit(retval);             /*child exits with user-provided return code*/
               }
                else {
    
    
                        printf("Parent:I am the parent process!\n");
                        printf("Parent:My PID is %d\n",getpid());
                        printf("Parent:The value of my child's PID is %d\n", childpid);
                        printf("Parent:I will now wait for my child to exit.\n");
                        wait(&status);
                        printf("Parent:Child's exit code is %d\n",WEXITSTATUS(status));
                        printf("Parent:Goodbye!\n");
                        exit(0);

                }

        }
        else {
    
    
                perror("fork error\n");
                exit(0);
        }

        return 0;
}

2. Código para el Experimento 2

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

int main() {
    
    

        int rtn;                     /*the return  value of the son process*/
        if (fork() == 0) {
    
    
                /*The son process execution this process */
                execlp("/bin/ls","ls -al",(char *)0);

                exit(21);   /*If the exec function return it's program,
                             that indicate it didn't exec the order normally,
                             so it must print the failure information*/
        }
        else {
    
    
                /*the father process, is waiting the end of the son process and print the return value of the son process*/
                wait(&rtn);
                printf("child process return %d\n", rtn);
        }

        return 0;
}

4. Resultados experimentales

Experimento 1 ejecutando resultados:

inserte la descripción de la imagen aquí

Resultados de la ejecución del experimento 2

inserte la descripción de la imagen aquí

5. Resumen y razonamiento experimental
(1) Resuma las tres situaciones de retorno de llamar a la función fork()
Cuando el valor de retorno de la función fork es menor que 0, significa que el proceso secundario no se creó con éxito. El proceso original aún se está ejecutando.
Cuando el valor de retorno de la función de bifurcación es 0, significa que el proceso secundario se creó con éxito y el proceso actual es un proceso secundario.
Cuando el valor de retorno de la función de bifurcación es mayor que 0, significa que el valor de retorno es el valor de retorno del proceso principal
(2) Resumen fork() Cuando se usa junto con wait(), intente cancelar la función wait() en el proceso principal y observe el estado de ejecución del proceso. La función
de la función wait ():
una vez que el proceso principal llama a esperar, se bloqueará de inmediato y esperar analizará automáticamente si el proceso actual Un proceso secundario ha salido, si encuentra un proceso secundario que se ha convertido en un zombi, wait recopilará la información de este proceso secundario, lo destruirá por completo y regresará; si no encuentra dicho proceso secundario, wait bloqueará aquí hasta que aparezca uno.

La función Wait () debe usarse junto con la función fork (). Si la función wait () se usa antes que la función fork (), devuelve -1; normalmente se llama en el proceso principal y devuelve el PID del proceso hijo

Cancele la función esperar () en el proceso principal. Dado que no hay función de espera, el proceso principal se ejecutará hasta el final del proceso, y luego el proceso secundario se convertirá en un proceso zombi cuando se ejecute. El resultado de la ejecución es

inserte la descripción de la imagen aquí

(3) Resumir y verificar el uso específico de las funciones de la familia ejecutiva.

Uso de seis funciones y parámetros correspondientes
int execl(const char *ruta, const char *arg, …)
int execv(const char *ruta, char *const argv[])
int execle(const char *ruta, const char *arg , …, char *const envp[])
int execve(const char *path, char *const argv[], char *const envp[])
int execlp(const char *file, const char *arg, …)
int execvp( const char *archivo, char *const argv[])

El valor de retorno de la función es exitoso: la función no devolverá
Error: devuelve -1, el motivo del error se registra en error

Tome la función execlp como ejemplo, execlp("/bin/ls", "ls -al", (char *)0); Use "ls -al" para mostrar todos los archivos en el directorio actual.
inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/weixin_45788387/article/details/120815274
Recomendado
Clasificación