Cómo configurar un demonio en segundo plano multiproceso
Primero, veamos algunos demonios comunes del sistema y veamos cómo se relacionan con varios conceptos: grupos de procesos, terminales de control y sesiones. El comando p s imprime el estado de cada proceso en el sistema. Este comando tiene múltiples opciones; consulte el manual del sistema para obtener más detalles. Para ver la información requerida, ejecute: ps -axj.
PPID PID PGID SID TTY TP GID STAT UID TIME comando
0 1 0 0 ?-1 S 0 0:04 inicialización
1 2 1 1 ? -1 SW 0 0:00 [keventd]
1 3 1 1 ?-1 SW 0 0:00 [kapm-idled]
0 4 1 1 ?-1 SWN 0 0:00[ksoftirqd_CPU 0]
0 5 1 1 ?-1 SW 0 0:00 [kswapd]
0 6 1 1 ?-1 SW 0 0:00 [kreclaimd ]
0 7 1 1 ?-1 SW 0 0:00 [bdflush]
0 8 1 1 ?-1 SW 0 0:00[kupdate] p>
1 9 1 1 ?-1 SW lt;0 0:00 [mdrecoveryd]
1 17 1 1 ?-1 SW 0 0:02 [kjournald]
1 92 1 1 ?-1 SW 0 0:00 [khubd]
1 573 573 573 ?-1 S 0 0:03 syslogd -r -x
1 578 578 578?- 1 S 0 0:00 klogd -2
1 598 598 598?-1 S 32 0:00Mapeo de puertos
Estos procesos con números de proceso 1 y 2 son muy especiales y existen en todo el ciclo de vida del sistema. No tienen ID de proceso principal, ID de proceso de grupo ni ID de sesión. El demonio syslogd se puede utilizar en cualquier programa que registre mensajes del sistema para los operadores. Puede imprimir estos mensajes en la consola real o escribirlos en un archivo. Sendmail es un demonio de correo estándar. El programa de actualización escribe periódicamente (normalmente cada 30 segundos) el contenido de la memoria caché del núcleo en el disco duro. Para hacer esto, el programa llama a la función sync(2) cada 30 segundos. El demonio cron ejecuta comandos específicos en fechas y horas específicas. Muchas tareas de gestión del sistema se implementan mediante cron que ejecuta periódicamente programas relacionados. El proceso inetd escucha las interfaces de red del sistema en busca de solicitudes entrantes a varios servidores de red. El último demonio, lpd, maneja todas las solicitudes de impresión del sistema.
Tenga en cuenta que todos los demonios se ejecutan con prioridad de superusuario (ID de usuario 0). Ninguno de los demonios tiene una terminal de control, el nombre de la terminal está establecido en un signo de interrogación (?) y el ID del grupo de procesos en primer plano de la terminal está establecido en -1.
La falta de una terminal de control es el resultado de que el demonio llama a setsid. Todos los demonios, excepto los de actualización, son el primer proceso en los grupos de procesos y sesiones, y son los únicos procesos en esos grupos de procesos y sesiones. Finalmente, cabe señalar que el proceso padre de todos estos demonios es el proceso de inicio.
Antes de entrar en la programación real, veamos el concepto de escribir un demonio: una sesión de composición de procesos.
Grupo de procesos
Además del ID del proceso, cada proceso pertenece a un grupo de procesos (los grupos de procesos participarán cuando se analicen las señales). Un grupo de procesos es una colección de uno o más procesos. Cada proceso tiene un ID de grupo de procesos único. El ID del grupo de procesos es similar al ID del proceso: es un número entero positivo que se puede almacenar en el tipo de datos pid_t.
Cada grupo de procesos tiene un proceso líder de equipo. La identidad de un proceso líder es que su ID de grupo de procesos es igual a su ID de proceso. El líder de un grupo de procesos puede crear un grupo de procesos, crear procesos en el grupo y luego finalizarlo. Mientras haya un proceso en el grupo de procesos, el proceso existe independientemente de si se termina el proceso de liderazgo. El intervalo de tiempo desde la creación de un grupo de procesos hasta la salida del último proceso se denomina vida útil del grupo de procesos. El último proceso de un grupo de procesos puede terminar o unirse a otro grupo de procesos.
Como se mencionó anteriormente, un proceso que llama a setgid puede unirse a un grupo existente o crear un nuevo grupo de procesos (setsid también puede crear un nuevo grupo de procesos, que se usará más adelante).
Tiempo de conversación
Una sesión es una colección de uno o más grupos de procesos. Entre ellos, hay tres grupos de procesos en una sesión y, por lo general, hay canales de shell para agrupar varios procesos.
Las siguientes son algunas funciones sobre sesiones y grupos de procesos:
Una sesión puede tener un terminal de control independiente, normalmente el dispositivo terminal en el que iniciamos sesión (login de terminal) o un pseudo terminal dispositivo (inicio de sesión de red), pero este terminal de control no es necesario.
El primer proceso de sesión para establecer una conexión con el terminal de control se denomina proceso de control. Varios grupos de procesos en una sesión se pueden dividir en un grupo de procesos en primer plano y uno o varios grupos de procesos en segundo plano.
Si una sesión tiene un terminal de control, tiene un grupo de procesos en primer plano y otros grupos de procesos son grupos de procesos en segundo plano. Siempre que escriba una tecla de interrupción (generalmente eliminar o ctrl-c) o una tecla de salida (generalmente ctrl-/), se enviará una señal de interrupción o una señal de salida a todos los procesos en el futuro grupo de procesos.
Reglas de programación para demonios
En diferentes entornos Unix, los detalles de programación específicos de los demonios no son consistentes. Afortunadamente, los principios de programación de los procesos demonio son en realidad los mismos y la única diferencia son los detalles de implementación específicos. Este principio es para satisfacer las características del proceso demonio. Las reglas de programación son las siguientes:
1. Ejecutar en segundo plano
Para evitar que el terminal de control se cuelgue, el proceso del demonio debe ejecutarse en segundo plano. El método consiste en llamar a fork en el proceso para finalizar el proceso principal y dejar que el demonio se ejecute en segundo plano en el proceso secundario. Específicamente, llamar a fork y luego hacer que el proceso principal salga hace lo siguiente:
Primero, si el proceso del asistente se inició mediante un simple comando de Schell, luego finalizar el proceso principal hace que Schell El comando se considere ejecutado .
En segundo lugar, el proceso hijo hereda el ID del grupo de procesos del proceso padre, pero tiene un nuevo ID de proceso, lo que garantiza que el proceso hijo no sea el primer proceso en un grupo de procesos. Este es un requisito previo necesario para la próxima convocatoria de s.e.t.s.i.d.
2. Salga del terminal de control e inicie sesión en el grupo de sesión y proceso.
Una sesión de inicio de sesión puede contener múltiples grupos de procesos que comparten una terminal de control, que suele ser la terminal de inicio de sesión y la terminal de control del proceso de creación. Las sesiones de inicio de sesión y los grupos de procesos generalmente se heredan del proceso principal. Nuestro objetivo es deshacernos de ellos para que no se vean afectados.
El método consiste en llamar a setsid() basándose en el primer punto para convertir al proceso en líder de la sesión:
Cabe señalar que cuando el proceso es el líder de sesión, setsid( ) la llamada fallará, pero el primer punto ya asegura que el proceso no es el líder de la sesión. Después de una llamada exitosa a setsid(), el proceso se convierte en el nuevo líder de sesión y en el nuevo líder de proceso, y se separa de la sesión de inicio de sesión original y del grupo de procesos. Debido a la exclusividad del proceso de sesión con el terminal de control, el proceso se desacopla simultáneamente del terminal de control.
Específicamente, la operación es:
(a) Convertirse en el primer proceso en el nuevo período de diálogo
(b) Ser el primer proceso en el nuevo proceso El proceso del grupo A
(c) no tiene terminal de control.
3. Prohibir que el proceso vuelva a abrir la terminal de control.
El proceso ahora se ha convertido en líder de sesión sin terminal, pero puede volver a solicitar abrir una terminal de control. Puede evitar que un proceso vuelva a abrir el terminal de control haciéndolo dejar de ser el líder de la sesión:
4.
El proceso hereda los descriptores de archivos abiertos del proceso principal que lo creó. Si no se cierra, se desperdiciarán recursos del sistema, lo que provocará que el sistema de archivos donde se encuentra el proceso se desmonte y se produzcan errores impredecibles. En términos generales, es necesario cerrar tres descriptores de archivo 0, 1 y 2, que son entrada estándar, salida estándar y error estándar. Porque generalmente queremos que el demonio tenga un sistema de entrada y salida de información, en lugar de enviar todo a la pantalla del terminal. Llame a fclose();
5. Cambie el directorio de trabajo actual
Cambie el directorio de trabajo actual al directorio raíz. El directorio de trabajo actual heredado del proceso principal puede estar ubicado en el sistema de archivos ensamblador. Debido a que el proceso del asistente generalmente existe hasta que se reinicia el sistema, si el directorio de trabajo actual del proceso del asistente está en un sistema de archivos ensamblador, el sistema de archivos no se puede desensamblar. Además, algunos procesos del asistente pueden cambiar el directorio de trabajo actual a una ubicación específica y funcionar allí. Por ejemplo, los procesos del asistente de cola de impresión de línea a menudo cambian su directorio de trabajo a su directorio de cola de impresión.
Puedes llamar a chdir("directory");
6. Restablecer la máscara de creación de archivos
Establece la máscara de creación de archivos en 0. La creación de máscaras mediante métodos de archivos heredados puede impedir la configuración de ciertos permisos. Por ejemplo, si el proceso del asistente quiere crear un archivo que un grupo pueda leer y escribir, y el método de archivo heredado crea una máscara que bloquea ambos permisos, la lectura y escritura del grupo requerida no funcionará.
7. Procesamiento de la señal SIGCHLD
No es necesario procesar la señal SIGCHLD. Sin embargo, para algunos procesos, especialmente los procesos del servidor, el subproceso de producción tiende a solicitar cuando llega la solicitud. Si el proceso padre no espera a que finalice el proceso hijo, el proceso hijo se convertirá en un proceso zombie y seguirá ocupando recursos del sistema. Si el proceso principal espera a que finalice el proceso secundario, aumentará la carga sobre el proceso principal y afectará el rendimiento de concurrencia del proceso del servidor. En el sistema v, la operación de la señal SIGCHLD se puede configurar simplemente en SIG-IGN:
Signal (SIGCHLD, SIG_IGN
De esta manera el kernel no terminará en el niño); Process Los procesos Zombie se generan cuando se ejecutan, lo cual es diferente de BSD4. Bajo BSD4, los procesos zombies deben aparecer hasta que finalice el proceso hijo.
Instancia de proceso de demonio
La instancia de proceso de demonio consta de dos partes: el programa principal test.c y el programa de inicialización init.c. El programa principal informa al registro test.log. en el directorio /tmp cada minuto. Estado de ejecución. La función init_daemon en el inicializador es responsable de generar el proceso del demonio.
void make_daemon(void)
{
pid _ t pid
ARCHIVO * lockfd
sigset _ t sighup
int I;
extern PID_t getsid(PID_t);
PID = fork();//Generar el primer proceso hijo
if(PID lt; 0) {
printinfo("¡error de bifurcación!", error de información);
Salir (salida fallida);
p>
} else if(PID gt; 0) {
printinfo("fork 1 ok!", pantalla de información);
Salir (OKEXIT); El proceso padre se deshace del control del shell.
}
PID = getpid(); //Obtiene la identificación del proceso hijo.
lockfd = fopen(PIDFILE, " w "); // Lo siguiente es escribir el pid en un archivo.
if (lockfd!= NULL) {
fprintf(lockfd, " d/n ", PID
fclose(lockfd
}//Escribe pid
if (getsid(0)!= pid) {//Crea una nueva sesión.
if(setsid() lt; 0) {
printinfo("backupdaemon setsid error!", error de información);
perror(" setsid ") ;
}
}
If(pid=fork()){// Generar un proceso hijo nuevamente, esta vez un proceso nieto.
Salir (0); //Salir del proceso de generación anterior
} else if(PID lt; 0){
Salir (1); p> p>
}
Close(1); //Cerrar el archivo
Close(2);
chdir(rundir); /Cambiar el directorio de ejecución
umask(022); //Cambiar los permisos del archivo
}
El demonio de salida de error no pertenece a ningún terminal, por lo que cuando necesita generar cierta información Cuando se ejecuta, no puede enviar información directamente a la salida estándar y a la salida de error estándar como un programa normal. La mayoría de las veces, no queremos que cada demonio escriba su propio mensaje de error en un archivo separado. Porque sería un dolor de cabeza para el administrador del sistema recordar qué demonio escribió qué archivo de registro y verificar estos archivos con regularidad. Por lo tanto, necesitamos un mecanismo centralizado de registro de errores del demonio. Actualmente, muchos sistemas han introducido procesos de grabación syslog para lograr este objetivo. Desde el desarrollo y uso generalizado de BSD syslog en Berkeley, la mayoría de los procesos demonio han utilizado el mecanismo BSD syslog. A continuación presentaremos el uso de BSD syslog. Hay tres formas de generar mensajes de registro:
1 Las rutinas del kernel pueden llamar a la función de registro. Cualquier proceso de usuario puede leer estos mensajes abriendo y leyendo el dispositivo /dev/klog. Como no tenemos intención de escribir rutinas en el núcleo, esta función no se explicará más.
La mayoría de los procesos de usuario (procesos demonio) llaman a la función syslog para generar mensajes de registro. Explicaremos su secuencia de llamadas a continuación.
Esto hace que los mensajes se envíen a los sockets /dev/log de Windows del datagrama del dominio Unix.
Los procesos de usuario en este host u otros hosts conectados a este host a través de una red TCP/IP pueden enviar mensajes de registro al puerto UDP 514. NOTA: Las funciones syslog no generan estos datagramas UDP; requieren una programación de red explícita por parte del proceso que genera este mensaje de registro. Normalmente, el demonio syslog lee los mensajes registrados en tres formatos. Este demonio lee el archivo de configuración al inicio. Generalmente, su nombre de archivo es /etc/syslog.conf y determina dónde se deben enviar los diferentes tipos de mensajes. Por ejemplo, los mensajes de emergencia se pueden enviar al administrador del sistema (si está conectado) y mostrarse en la consola, mientras que los mensajes de advertencia se pueden registrar en un archivo. Este mecanismo proporciona la función syslog y su formato de llamada es el siguiente
#Includes
void openlog (char*ident, int option, int facility);
void syslog (int prioridad, char*format,...)
void close log();
Llamar a openlog es opcional. Si no se llama a openlog, se llamará automáticamente a openlog la primera vez que se llame a syslog. Llamar a closelog también es opcional, simplemente cierra el descriptor utilizado para comunicarse con el demonio syslog. Llamar a openlog nos permite especificar una identificación que se agregará a cada mensaje registrado en el futuro. Ident es generalmente el nombre del programa (por ejemplo, cron, inetd, etc.). Hay cuatro posibilidades para las opciones: LOG_CONS Si el mensaje de registro no se puede enviar a syslog a través de datagramas de dominio Unix, se escribirá en la consola. LOG_NDELAY1 abrirá inmediatamente un socket de Windows de datagrama de dominio Unix al demonio syslog en lugar de esperar a que se registre el primer mensaje. Normalmente, un socket de Windows no se abre hasta que se registra el primer mensaje. LOG_PERROR no solo envía mensajes de registro a syslog, sino que también los envía a error estándar. Esta opción sólo es compatible con 4.3BSDReno y superiores. LOG_PID Cada mensaje contiene el ID del proceso. El demonio puede usar esta opción para bifurcar un proceso hijo para cada solicitud. El propósito de configurar el parámetro de instalación en openlog es permitir que el archivo de configuración interprete mensajes de diferentes instalaciones para procesarlos de diferentes maneras. Si no se llama a openlog, o se llama con una función 0, entonces esta función se puede describir como parte del parámetro de prioridad al llamar a syslog. Llame a syslog para generar mensajes de registro. Su parámetro de prioridad es una combinación de instalación y nivel, con valores opcionales como se muestra a continuación. Los valores de nivel están ordenados de mayor a menor prioridad.