Comprensión de los procesos de Linux

  
        En general, un proceso es un programa o código que se está ejecutando. Sabemos que el programa en sí es un montón de código, almacenado en el disco al principio, cuando es estático, inanimado, solo cuando el código del programa se carga en la memoria, el código tiene vida, puede ser movido dinámicamente por la CPU Ejecución El problema es que el sistema operativo actual puede ejecutar múltiples programas en paralelo, es decir, el código que almacena múltiples programas en la memoria al mismo tiempo. Para facilitar la administración, es necesario organizarlos de manera razonable. La forma es agregar algunos metadatos a cada parte del código por el sistema operativo. Estos metadatos son la PCB, que es el bloque de control de tareas. No es difícil entender que el código de cada programa se puede dividir en dos partes: los datos de la instrucción. Las instrucciones son las diversas operaciones especificadas por el código del programa; los datos son el objeto de estas operaciones. Un programa se puede cargar en la memoria varias veces en varios procesos, como abrir dos vim al mismo tiempo para editar diferentes archivos. Entonces la pregunta es: ¿Es necesario almacenar en la memoria varias copias de las instrucciones del programa al mismo tiempo? La respuesta no es necesaria. La parte de instrucciones se establece en solo lectura y permite que este código se comparta entre dos o más procesos que se ejecutan en el sistema, la parte de datos es privada para cada proceso y no se puede compartir. Por ejemplo, cada vim solo puede editarse por sí misma. Archivo Entonces, ¿qué hay en el PCB? Identificación del proceso. Cada proceso en el sistema tiene una identificación única, que está representada por el tipo pid_t en C, que en realidad es un número entero no negativo. El estado del proceso, como correr, suspender, detener, zombies, etc. Algunos registros de CPU que deben guardarse y restaurarse cuando el proceso cambia. Describe la información del espacio de direcciones virtuales. Describe la información que controla el terminal. Directorio de trabajo actual. Máscara de Umask. Una tabla de descriptores de archivos que contiene varios punteros a la estructura de archivos. Información relacionada con la señal. ID de usuario y de grupo. Control de terminales, sesiones y grupos de proceso. El límite de recursos que puede utilizar el proceso. Se puede ver que la estructura de la PCB es bastante complicada para controlar el proceso. La creación del proceso a menudo oye "Crear un proceso", ¿qué está pasando? Lo primero en lo que se puede pensar es que el proceso no es un mono nieta. Es imposible descubrirlo por sí mismo. Debe ser la "vida" de otra persona. En Linux, el proceso es creado por el proceso principal. Para ser precisos, la parte de instrucciones del código en el proceso principal utiliza activamente la función fork () para crear el proceso, y luego se "sintetiza" un proceso secundario. ¿Cómo funciona la función de horquilla? Como cada proceso tiene una PCB, primero debe solicitar una PCB con el sistema operativo (la PCB es limitada), luego asignar la nueva memoria de proceso y luego copiar el código del proceso principal. De hecho, la bifurcación es muy lenta para copiar el proceso principal, es decir, durante la llamada a la función de bifurcación, habrá dos procesos casi idénticos en la memoria, excepto el número de proceso (que es único). Después de que se copie el proceso, ambos procesos tienen una función de bifurcación a la espera de regresar (tenga en cuenta que es un retorno, ya que la misma función de bifurcación es también una pieza de código, la parte anterior completa la función de copia, después de que aparece el proceso secundario, regresa a la parte El código es), y sus resultados de retorno son diferentes (el sistema operativo controla el resultado de retorno): la bifurcación en el proceso principal devuelve el pid del proceso secundario, la bifurcación en el proceso secundario devuelve 0; si la bifurcación falla, la devolución es -1 . Fork acaba de crear dos procesos casi idénticos, ejecutan el mismo código, que es diferente de lo que se dijo al principio, porque creamos un nuevo proceso que se utiliza principalmente para ejecutar el nuevo código. En este momento necesitamos la función de clase exec, cuando el proceso llama a una función exec, el código del programa se reemplaza completamente por el nuevo programa, a partir de la rutina de inicio del nuevo programa. Llamar a exec no crea un nuevo proceso, por lo que el ID del proceso no cambia antes y después de que se llame a exec. Si la llamada es exitosa, el nuevo programa se carga desde el código de inicio y ya no se devuelve. Si la llamada falla, devuelve -1, por lo que la función exec solo tiene el valor de retorno del error y no tiene un valor de retorno exitoso. La llamada al sistema exec pasa los argumentos de la línea de comando y las tablas de variables de entorno a la función principal al ejecutar el nuevo programa. La tabla de variables de entorno es una descripción del entorno del sistema en el que se encuentra el proceso. Si un fragmento de código se va a ejecutar normalmente, debe usar varios recursos del sistema. La tabla de variables de entorno es una abstracción de la misma. Sin embargo, la función de clase ejecutiva debe llamarse explícitamente, ¡y el proceso hijo no cargará activamente el nuevo código de programa! Por lo tanto, generalmente está en el código del proceso principal, de acuerdo con el valor de retorno de la bifurcación para escribir una rama, la rama del proceso hijo llama explícitamente a exec. La terminación de un proceso terminará todos los descriptores de archivo cuando finalice, liberando la memoria asignada en el espacio de usuario, pero su PCB permanece, y el sistema operativo guarda cierta información en él: si es una terminación normal, guarda el estado de salida. Si se termina de forma anormal, retiene la señal que causó la finalización del proceso. El padre de este proceso puede llamar a wait o waitpid para obtener esta información y luego limpiar completamente el proceso. Sabemos que el estado de salida de un proceso se puede ver en el shell con la variable especial $? Porque el shell es su proceso principal. Cuando finaliza, el shell llama a waitpid para obtener su estado de salida y limpia completamente el proceso. Si un proceso ha finalizado, pero su proceso principal aún no ha llamado esperar o esperar para limpiarlo, el estado del proceso se llama proceso Zombie. Cualquier proceso que acaba de terminar es un proceso zombie. En circunstancias normales, el proceso principal limpia el proceso zombie de inmediato. Si un proceso principal finaliza y sus procesos secundarios aún existen (estos procesos secundarios aún se están ejecutando, o ya son procesos zombie), los procesos principales de estos procesos secundarios se cambian a procesos iniciales. Init es un proceso especial en el sistema. Por lo general, el archivo del programa es /sbin /init y el identificador del proceso es 1. Es responsable de iniciar varios servicios del sistema cuando se inicia. Después de eso, es responsable de limpiar el proceso hijo. Mientras el proceso hijo finalice, init Llame a la función de espera para limpiarlo. El proceso zombie no se puede limpiar con el comando kill porque el comando kill solo se usa para finalizar el proceso y el proceso zombie ha finalizado. Así que una forma viable es matar su proceso padre. Los prototipos de las funciones wait y waitpid son:
 #include #include pid_t wait (int * status); pid_t waitpid (pid_t pid, int * status, int options); 

Si la llamada se realiza correctamente, se devuelve el proceso hijo que se ha limpiado. Id, devuelve -1 si la llamada es errónea. Cuando el proceso principal llama o espera, puede: + bloquear (si todos sus procesos secundarios todavía se están ejecutando). + La información de terminación con el proceso hijo se devuelve inmediatamente (si un proceso hijo ha terminado, en espera de que el proceso padre lea su información de terminación). + Error devuelve inmediatamente (si no tiene ningún proceso hijo).

Copyright © Conocimiento de Windows All Rights Reserved