#Linux 中 的 GCC 规划 # Conocimientos relacionados con los procesos

Basado en C, estudiar más a fondo las funciones del kernel de Linux, funciones a nivel de sistema

Agosto de 2017

1. Conocimiento

1.1 Conceptos básicos:

(1) El programa
es un archivo ejecutable almacenado en un disco.
(2) El proceso
es la instancia de ejecución del programa. Cada proceso tiene permisos y responsabilidades independientes y se ejecuta en su propio espacio de direcciones virtuales.
Los procesos no se afectarán entre sí, pero pueden comunicarse.
(3) ID de proceso, el ID de proceso denominado PID es un
número entero no negativo, el identificador digital del proceso.
Cola de tareas de proceso

1.2 Rutina de inicio

(1) La "rutina de inicio" se compila y se ejecuta antes que main.
(2) Recopile los parámetros de la línea de comandos y páselos a argc y argv en main. Y la tabla de entorno envp.
(3) Registre la "función de terminación" atexit ().

1.3 Terminación del proceso

(1) Terminación normal

  • Regresar de la función principal (regresar)
  • Salida de llamada (función de biblioteca C estándar)
  • Llamar a _exit o _Salir (llamada al sistema)
  • El último hilo regresa de la "rutina de inicio"
  • El último hilo llama a pthread_exit

Nota:
return y exit () actualizarán la caché de E / S estándar y llamarán automáticamente a la función de terminación.
_exit () y _Salir (), ni actualizar ni llamar.

(2) Terminación anormal

  • Anular llamada
  • Recibe una señal y termina
  • El último hilo responde a la solicitud "cancelar"

(3) Proceso de devolución

  • Por lo general, el programa devuelve 0 con éxito, de lo contrario, devuelve un valor distinto de cero
  • En el shell, puede producir el valor de retorno del proceso (echo $?)

(4) Función de terminación

#include <stdio.h>
int atexit(void (*function)(void));
向内核登记终止函数,成功返回0,否则-1
  • Cada proceso iniciado registra una función de terminación estándar por defecto
  • La función de terminación libera algunos recursos ocupados por el proceso cuando el proceso termina
  • Registre múltiples funciones de terminación y la secuencia de ejecución se ejecuta en una pila, primero se registra y luego se ejecuta.

1.4 Esquemático

Diagrama de inicio

1.5 Límite de recursos de proceso

Los recursos disponibles en linux son los siguientes:

RLIMIT_AS 			进程可用的存储区大小
RLIMIT_CORE 		core文件最大字节数
RLIMIT_CPU 			CPU时间最大值
RLIMIT_DATA			数据段最大长度
RLIMIT_FSIZE		可创建文件的最大长度
RLIMIT_LOCKS		文件锁的最大数
RLIMIT_MEMLOCK使用mlock能否在存储器中锁定的最长字节数
RLIMIT_NOFILE		能打开的最大文件数
RLIMIT_NPROC		每个用户ID可拥有的最大子进程数
RLIMIT_RSS			最大驻内存集的字节长度
RLIMIT_STACK		栈的最大长度
  1. archivo de cabeza
#include <sys/resource.h>

struct rlimit{
	rlim_t rlim_cur;/*软件限制:当前限制*/
	rlim_t rlim_max;/*硬件限制:当前限制可以达到的最大值*/
}
  1. función
(1)获取进程的资源限制,存放在rlptr指向 的结构体中。成功返回0,失败非0。
int getrlimit(int resource , struct rlimit *rlptr);

(2)修改resource指定的资源限制,通过rlptr指向的结构体。成功返回0
int setlimit(int resource,const struct rlimie *rlptr);
  1. Archivo de configuración
    (1) /etc/security/limits.conf
    (2) En Linux, la inicialización de los recursos del proceso se establece en el proceso 0 y se hereda en los procesos posteriores.
  2. Reglas de modificación para los límites de recursos
    (1) El límite de recursos de hardware debe ser mayor o igual que el límite de software.
    (2) Cualquier proceso puede reducir o aumentar su límite de recursos de software, pero debe ser mayor que su límite de software. Los usuarios comunes no pueden revertir esta operación.
    (3) El superusuario puede aumentar el límite de hardware.

2. Instrucciones relacionadas con el proceso

2.1 instrucción PS

Puede ver: ID de proceso (PID), ID de usuario de proceso, estado de proceso STAT, comando de proceso, etc.

3. Estado común del proceso

3.1 Estado operativo

El proceso actual del sistema
Proceso de estado listo
PS columna de estado de comando == R

3.2 Estado de espera

Esperando que ocurra el evento
Esperando
la columna de estadísticas del recurso del sistema Comando PS == S

3.3 Estado de parada

La columna de estadísticas del comando PS == T

3.4 Estado zombi

El proceso termina o termina
. Todavía hay
una columna de estadísticas que registra el comando PS en la entrada de la tabla de proceso == Z

3.5 Relación de transformación del estado del proceso

Relación de transformación del estado del proceso

4. Programación de procesos

4.1 Pasos generales

(1) Procesar el trabajo en el kernel
(2) Procesar el proceso actual
(3) Seleccionar el proceso (proceso en tiempo real y proceso normal)
(4) Intercambio de procesos

4.2 Información de programación en task_struct

(1) Estrategia

  • Estrategia de rotacion
  • Estrategia de primero en entrar, primero en salir

(2) Prioridad

  • variable jiffies

(3) Prioridad en tiempo real

  • Entre procesos en tiempo real

(4) Contador

5. Identificación del proceso

Los procesos tienen muchos identificadores:
ID de proceso actual, ID de usuario real, ID de usuario efectivo, ID de grupo de usuarios, ID de proceso principal, ID de grupo de procesos.
Funciones relacionadas con esto:

  1. archivo de cabeza
#include <unistd.h>
#include <sys/types.h>
  1. Función para obtener ID de proceso
pid_t getpid(void);           //获取当前进程的ID标识
pid_t getppid(void);         //获取父进程的ID标识
pid_t getpgrp(void);        //获取当前进程所在的进程组ID标识。
pid_t getpgid(pid_t pid);  //获取指定ID的进程所在的进程组ID标识。

uid_t getuid(void);           //获取当前进程的 实际用户ID
uid_t geteuid(void);          //获取当前进程的 有效用户ID

gid_t getgid(void);           //获取当前进程的用户组ID

6. Creación de procesos

El contenido clave de este artículo.

6.1 Bifurcación de funciones para crear un proceso hijo


  1. El nuevo proceso creado por la función fork se denomina proceso hijo. Esta función se llama una vez y regresa dos veces.
    La diferencia entre devolver dos veces:
    (1) En el proceso padre, se devuelve el ID de proceso del nuevo proceso hijo.
    (2) En el nuevo proceso hijo, se devuelve 0. Porque se recrean el segmento de datos, el montón y la pila del proceso hijo.
    (3) La secuencia en ejecución de los procesos padre e hijo se determina automáticamente de acuerdo con la programación del sistema.
    (4) El proceso hijo copia el espacio de memoria del proceso padre.

  2. La función vfork
    es similar a fork, pero el proceso hijo se ejecuta primero y no copia el espacio de memoria del proceso padre.

  3. Atributos heredados de procesos secundarios

  • Información y permisos del usuario
  • Información de directorio, información de señal, entorno, restricciones de recursos
  • Segmento de memoria compartida, montón, pila y segmento de datos, segmento de código compartido
  1. Atributos únicos de procesos secundarios
  • Identificacion de proceso
  • Bloquear información
  • horas de operación
  • Señal pendiente
  1. La estructura del kernel cambia al operar archivos
  • El proceso hijo hereda la tabla de descripción de archivos, pero no hereda, pero comparte las entradas de la tabla de archivos y los i-nodos.
  • Después de que se crea un proceso hijo, el contador de referencia en la entrada de la tabla de archivos aumenta en 1 para convertirse en 2. Cuando el proceso padre realiza una operación de cierre, el contador disminuye en 1. El proceso hijo aún puede usar entradas de la tabla de archivos. Solo cuando el contador sea 0, se liberará la entrada del archivo.

6.2 Grupo de funciones ejecutivas parasitarias del proceso

  • La función exec se usa para ejecutar otro programa. El programa recién ejecutado reemplazará el texto, los datos, el montón y la pila del proceso original.
  • exec no crea un nuevo proceso, el ID del proceso antes y después no ha cambiado.
  • Después de que fork crea un proceso hijo, puede usar la función exec para ejecutar otro programa en el proceso hijo.
  1. archivo de cabeza
#include <unistd.h>

2. Función

//list 列出每个字符参数
int execl(const char *pathname,const char *arg0, ... /*(char*)0*/);
//argv 字符数组
int execv(const char *pathname,char * const argv[]);
//list 列出每个字符参数,环境表
int execle(const char *pathname,const char *arg0, ... /*(char*)0,char* const envp[]*/);
//argv 字符数组,环境表
int execve(const char *pathname,char * const argv[],char* const envp[]);
//
int execlp(const char *pathname,const char *arg0, ... /*(char*)0*/);
//
int execvp(const char *pathname,char * const argv[]);

上述所有的返回:出错返回-1 ,成功不返回。

6.3 función del sistema

  • La función del sistema es un componente interno de un proceso hijo, y el proceso hijo llama a la función exec.
  1. archivo de cabeza
#include <stdlib.h>

2. Función

简化exec函数的使用,成功返回执行命令的状态,错误返回-1
int system(const char * command);

7. Varios procesos especiales

7.1 Demonio

  • Un daemon es un proceso con una larga vida. A menudo comienzan cuando el sistema se inicia y terminan cuando el sistema se apaga.
  • Todos los demonios se ejecutan con la prioridad de superusuario (el ID de usuario es 0).
  • El demonio no controla la terminal.
  • El proceso padre del daemon es el proceso init.

7.2 Proceso huérfano

  • Cuando el proceso padre termina, el proceso hijo se convierte en un proceso huérfano. Adoptado por el proceso 1 (proceso de inicio).

7.3 Proceso Zombie

  • El proceso hijo finaliza, pero la memoria no se libera por completo (task_struct en el kernel no se libera). Este proceso se convierte en un proceso zombi.
  • Cuando finaliza el proceso padre del proceso zombie, es adoptado por el primer proceso (proceso de inicio) y finalmente se recicla.
  • Cómo evitar el proceso zombie:
    (1) Deje que el proceso padre del proceso zombie se recicle. El proceso padre comprueba si el proceso hijo finaliza y se recicla a intervalos regulares. Llame a wait () o waitpid () para notificar al kernel que libere el proceso zombie.
    (2) Utilice la señal SIGCHLD para notificar el procesamiento. Y llame a wait () en el manejador de señales.
    (3) Deje que el proceso zombie se convierta en un proceso huérfano y sea reciclado por el proceso init.
  1. archivo de cabeza
#include <sys/types.h>
#include <sys/wait.h>
  1. función
(1)等待子进程退出并回收。防止僵尸进程。成功返回子进程ID,出错返回-1。
pid_t wait(int *status);

(2)wait函数的非阻塞版本。成功返回子进程ID,出错返回-1。
pid_t waitpid(pid_t pid , int * status ,int options);

	1)pid参数。
			pid==-1   //等待任一子进程,功能和wait等效。
			pid== 0   //等待 同进程组ID的任一子进程。
			pid >  0   //等待指定的子进程
			pid < -1   //等待 组ID等于(-pid)的任一子进程。
	2)status参数。为空时,等待回收【任意状态】结束的子进程。不为空,则等待【指定状态】结束的子进程。
         检查wait和waitpid函数返回终止状态的宏
				WIFEXITED/WEXITSTATUS(status)    //若为正常终止子进程返回的状态,则为真。
				WIFSIGNALED/WTERMSIG(status)    //若为异常终止子进程返回的状态,则为真。(接到一个不能捕捉的信号)
				WIFSTOPED/WSTOPSIG(status)     //若为当前暂停子进程返回的状态,则为真。
	3)options参数。
				WNOHANG    //若由pid指定的子进程没有退出,则立即返回。waitpid不阻塞,返回值为0。
				WUNTRACED    //若某实现支持 作业控制,则有pid指定的任一子进程状态已暂停,其状态自暂停以来还没有报告过,则返回其状态。

  1. La diferencia entre las funciones wait y waitpid
    (1) Antes de que termine un proceso hijo, wait bloquea a la persona que llama. waitpid no bloqueará.
    (2) espera espera todos los procesos secundarios; waitpid espera el proceso secundario especificado.

8. Grupo de procesos

  • Una colección de uno o más procesos
  • Puede recibir varias señales desde el mismo terminal. Señales comunes en el mismo grupo.
  • ID de grupo de proceso único
  • Cuando todos los procesos del grupo terminan, el grupo de procesos morirá.
  • El comando kill envía una señal al grupo de procesos.

8.1 Obtener el número de grupo de procesos

El artículo anterior ha dado:

#include <unistd.h>
pid_t getpgrp(void);        //获取当前进程所在的进程组ID标识。
pid_t getpgid(pid_t pid);  //获取指定ID的进程所在的进程组ID标识。

8.2 Proceso de líder

  • La creación de un grupo de procesos comienza con la incorporación del primer proceso (proceso de líder de grupo). El ID del proceso líder se utiliza como ID de grupo.
  • El proceso líder puede crear un grupo de procesos y los procesos en el grupo.
  1. archivo de cabeza
#include <unistd.h>
  1. función
(1) 将进程加入到指定的进程组中。成功返回0,错误返回-1。
int setpgid(pid_t pid,pid_t pgid);

(2) pid参数为指定的进程号,pgid为进程组。

8.3 Grupo de procesos de primer plano

  • En Linux, el grupo que recibe automáticamente las señales del terminal se convierte en el grupo de procesos en primer plano.
  • En el terminal, el grupo de procesos en primer plano recibe primero señales como CTRL + c.
  • Varios grupos de procesos iniciados por el shell, el grupo de procesos padre predeterminado es el grupo de procesos de primer plano.
  1. archivo de cabeza
#include <unistd.h>
  1. función
(1)获取前台进程组ID。成功返回 前台进程组ID,错误返回-1。
pid_t tcgetpgrp(int fd); 

(2)使用pgrpid,设置前台进程组ID
int tcsetpgrp(int fd,pid_t pgrpid);

(3)fd必须引用该会话的控制终端。0表示当前正在使用的终端。

Supongo que te gusta

Origin blog.csdn.net/Kshine2017/article/details/102624873
Recomendado
Clasificación