Los demonios son procesos que no se ejecutan directamente bajo el control del usuario, sino que funcionan en segundo plano. Por lo general, se inician al iniciar el sistema y se ejecutan continuamente hasta que el sistema se apaga. La única diferencia entre estos y los procesos normales es que no envían mensajes a la consola o pantalla de ninguna manera.

Así es como puede crear un demonio en una máquina Linux.

Una breve introducción a cómo se crean los demonios

Muchos demonios se ejecutan en el sistema y algunos ejemplos familiares de demonios son los siguientes:

  • corona: Hace que los comandos se ejecuten a la hora especificada
  • sshd: Permite iniciar sesión en el sistema desde máquinas remotas
  • httpd: Sirve páginas web
  • nfsd: permite compartir archivos a través de la red

Además, los procesos daemon generalmente se nombran para terminar con la letra d, aunque no es obligatorio.

Para que un proceso se ejecute como un demonio, se sigue la siguiente ruta:

  • Las operaciones iniciales, como leer archivos de configuración u obtener los recursos necesarios del sistema, deben realizarse antes de que el proceso se convierta en un demonio. De esta forma, el sistema puede informar al usuario sobre los errores recibidos y el proceso finalizará con un código de error apropiado.
    instagram viewer
  • Se crea un proceso en ejecución en segundo plano con init como su proceso principal. Para este propósito, primero se bifurca un subproceso desde el proceso init, y luego el proceso superior se termina con exit.
  • Debe abrirse una nueva sesión llamando a la función setsid y el proceso debe desconectarse de la terminal.
  • Todos los descriptores de archivos abiertos heredados del proceso principal se cierran.
  • Entrada estándar, saliday los mensajes de error se redirigen a /dev/null.
  • El directorio de trabajo del proceso debe cambiar.

¿Qué son las sesiones de daemon?

Después de iniciar sesión en el sistema a través de una terminal, los usuarios pueden ejecutar muchas aplicaciones a través del programa shell. Estos procesos deben cerrarse cuando el usuario sale del sistema. El sistema operativo agrupa estos procesos en sesiones y grupos de procesos.

Cada sesión consta de grupos de procesos. Puedes describir esta situación de la siguiente manera:

La terminal donde los procesos reciben sus entradas y envían sus salidas se llama terminal de control. Un terminal de control está asociado con una sola sesión a la vez.

Una sesión y los grupos de procesos en ella tienen números de identificación (ID); estos números de identificación son los números de identificación de proceso (PID) de los líderes de sesión y de grupo de proceso. Un proceso hijo comparte el mismo grupo que su proceso padre. Cuando varios procesos son comunicarse con el mecanismo de tubería, el primer proceso se convierte en el líder del grupo de procesos.

Creación de un proceso Daemon en Linux

Aquí verá cómo puede crear una función daemon. Para este propósito, creará una función llamada _demonio. Puede comenzar nombrando el código de la aplicación que se ejecutará como un demonio como prueba.c, y el código con el que creará la función daemon como demonio.c.

//test.c
#incluir <stdio.h>
En t_demonio(En t, En t);
En tprincipal()
{
getchar();
_demonio (0, 0);
getchar();
devolver0;
}
//daemon.c
#incluir <sys/tipos.h>
#incluir <sys/stat.h>
#incluir <stdlib.h>
#incluir <stdio.h>
#incluir <fcntl.h>
#incluir <unistd.h>
#incluir <linux/fs.h>
#incluir <linux/límites.h>
En t_demonio(En t nochdir, En t No cerrar){
pid_t pid;
pid = bifurcación(); // bifurcar el proceso padre
si (pid < 0) {
salida(EXIT_FAILURE);
}
si (pid > 0) {
salida(SALIR_ÉXITO);
}
devolver0;
}

Para crear un demonio, necesita un proceso en segundo plano cuyo proceso principal sea init. En el código anterior, _demonio crea un proceso secundario y luego elimina el proceso principal. En este caso, su nuevo proceso será un subproceso de init y continuará ejecutándose en segundo plano.

Ahora compile la aplicación con el siguiente comando y examine el estado del proceso antes y después _demonio se llama:

CCG-opruebaprueba.Cdemonio.C

Ejecute la aplicación y cambie a una terminal diferente sin presionar ninguna otra tecla:

./prueba

Puede ver que los valores relacionados con su proceso son los siguientes. Aquí, tendrás que usar el comando ps para obtener información relacionada con el proceso. En este caso, el _demonio todavía no se ha llamado a la función.

pd-c prueba -o "pid ppid pgid sid tty estadísticadominio"
# Producción
PID PPID PGID SID TT STAT COMANDO
10296 5119 10296 5117 puntos/2 S+ ./prueba

cuando miras el ESTADO campo, verá que su proceso se está ejecutando pero esperando que ocurra un evento fuera de programa que hará que se ejecute en primer plano.

Abreviatura Significado
S Esperando dormido a que suceda un evento
T Aplicación detenida
s Líder de sesión
+ La aplicación se ejecuta en primer plano.

Puede ver que el proceso principal de su aplicación es el shell como se esperaba.

pd-jp 5119 
# Producción
PID PGID SID TTY HORA CMD
5119 5119 5117 puntos/2 00:00:02 zsh

Ahora regrese a la terminal donde está ejecutando su aplicación y presione Ingresar para invocar el _demonio función. Luego mire la información del proceso en la otra terminal nuevamente.

pd-c prueba -o "pid ppid pgid sid tty estadísticadominio"
# Producción
PID PPID PGID SID TT STAT COMANDO
22504 1 22481 5117 pts/2 S ./prueba

En primer lugar, puede decir que el nuevo subproceso se está ejecutando en segundo plano ya que no ve el + personaje en el ESTADO campo. Ahora examine quién es el proceso padre del proceso usando el siguiente comando:

pd-jp 1 
​​​​​​​# Producción
PID PGID SID TTY HORA CMD
1 1 1? 00:00:01sistemad

Ahora puede ver que el proceso principal de su proceso es el sistemad proceso. Se mencionó anteriormente que para el siguiente paso, se debe abrir una nueva sesión y se debe desconectar el proceso de la terminal de control. Para ello, utiliza la función setsid. Agregue esta llamada a su _demonio función.

El fragmento de código a agregar es el siguiente:

si (setsid() == -1) 
devolver-1;

Ahora que ha inspeccionado el estado antes _demonio llamado, ahora puede eliminar el primero conseguir char función en el prueba.c código.

//test.c
#incluir <stdio.h>
En t_demonio(En t, En t);
En tprincipal()
{
_demonio (0, 0);
getchar();
devolver0;
}

Después de compilar y ejecutar la aplicación nuevamente, vaya a la terminal donde realizó sus revisiones. El nuevo estado de su proceso es el siguiente:

pd-c prueba -o "pid ppid pgid sid tty estadísticadominio"
​​​​​​​# Producción
PID PPID PGID SID TT STAT COMANDO
25494 1 25494 25494? S./prueba

Él ? firmar en el TT El campo indica que su proceso ya no está conectado a una terminal. Note que el PID, IDPG, y S.I.D. los valores de su proceso son los mismos. Su proceso es ahora un líder de sesión.

En el siguiente paso, cambie el directorio de trabajo al directorio raíz de acuerdo con el valor del argumento que pasó. Puede agregar el siguiente fragmento a la _demonio función para esto:

if (!nochdir) {
si (chdir("/") == -1)
devolver-1;
}

Ahora, de acuerdo con el argumento pasado, todos los descriptores de archivos se pueden cerrar. Agregue el siguiente código a la _demonio función:

#define NR_OPEN 1024
si (! no cerrar) {
para (i = 0; i < NR_ABIERTO; i++)
cerrar (yo);
abierto("/dev/nulo", O_RDWR);
doblar (0);
doblar (0);
}

Después de cerrar todos los descriptores de archivos, los nuevos archivos abiertos por daemon se mostrarán con los descriptores 0, 1 y 2 respectivamente. En este caso, por ejemplo, el imprimir los comandos en el código se dirigirán al segundo archivo abierto. Para evitar esto, los primeros tres identificadores apuntan a la /dev/null dispositivo.

En este caso, el estado final de la _demonio función será la siguiente:

#incluir <sys/tipos.h>
#incluir <sys/stat.h>
#incluir <stdio.h>
#incluir <stdlib.h>
#incluir <fcntl.h>
#incluir <errno.h>
#incluir <unistd.h>
#incluir <syslog.h>
#incluir <cadena.h>
En t_demonio(vacío){
//PID: ID del proceso
// SID: ID de sesión
pid_t pid, sid;
pid = bifurcación(); // bifurcar el proceso padre
si (pid < 0) {
salida(EXIT_FAILURE);
}
si (pid > 0) {
salida(SALIR_ÉXITO);
}
// Crear un S.I.D.porniño
sid = estableceid();
si (sid < 0) {
// FALLAR
salida(EXIT_FAILURE);
}
si ((chdir("/")) < 0) {
// FALLAR
salida(EXIT_FAILURE);
}
cerrar (STDIN_FILENO);
cerrar (STDOUT_FILENO);
cerrar (STDERR_FILENO);
mientras (1) {
// Algunas Tareas
dormir (30);
}
salida(SALIR_ÉXITO);
}

Este es un ejemplo de un fragmento de código que ejecuta el sshd aplicación como un demonio:

...
if (!(debug_flag || inetd_flag || no_daemon_flag)) {
En t fd;
si (demonio (0, 0) < 0)
fatal("daemon() falló: %.200s", estrerror (errno));
/* Desconectar del tty de control. */
fd = abierto (_PATH_TTY, O_RDWR | O_NOCTTY);
si >= 0) {
(vacío) ioctl (fd, TIOCNOTTY, NULL);
cerrar (fd);
}
}
...

Los demonios son importantes para la programación del sistema Linux

Los demonios son programas que realizan varias acciones de una manera predefinida en respuesta a ciertos eventos. Se ejecutan en silencio en su máquina Linux. No están bajo el control directo del usuario y cada servicio que se ejecuta en segundo plano tiene su daemon.

Es importante dominar los demonios para aprender la estructura del núcleo del sistema operativo Linux y comprender el funcionamiento de varias arquitecturas de sistemas.

¿Qué es un demonio?

Leer siguiente

CuotaPíoCuotaCorreo electrónico

Temas relacionados

  • linux
  • Núcleo de Linux
  • Programación
  • Programación en C

Sobre el Autor

Fatih Küçükkarakurt (5 artículos publicados)

Ingeniero y desarrollador de software aficionado a las matemáticas y la tecnología. Siempre le ha gustado la informática, las matemáticas y la física. Ha desarrollado proyectos de motores de juegos, así como aprendizaje automático, redes neuronales artificiales y bibliotecas de álgebra lineal. Además continúa trabajando en aprendizaje automático y matrices lineales.

Más de Fatih Küçükkarakurt

Suscríbete a nuestro boletín

¡Únase a nuestro boletín para obtener consejos técnicos, reseñas, libros electrónicos gratuitos y ofertas exclusivas!

Haga clic aquí para suscribirse