Programación de demonios de Linux

Demonio de Linux

1. Introducción al daemon

Daemon es uno de los tres tipos de procesos de Linux, es un proceso de servicio en segundo plano y siempre se ejecuta en segundo plano. Por lo general, se ejecuta cuando el sistema se inicia y finaliza cuando se apaga. El daemon es independiente de cualquier terminal, realizando periódicamente una determinada tarea o esperando procesar un evento específico.
Linux gestiona procesos en forma de sesiones y grupos de procesos, y cada proceso pertenece a un grupo de procesos. Número de sesión Una colección de uno o más grupos de procesos Por lo general, cuando un usuario abre una terminal, el sistema crea una sesión. Todos los procesos que se ejecutan a través del terminal pertenecen a esta sesión. Cuando se cierra la terminal, todos los procesos relacionados finalizarán. Sin embargo, el demonio puede superar esta limitación sin verse afectado por el cierre del terminal.

2. Escribiendo el demonio

La creación del demonio se divide en cinco pasos

2.1 Crear un proceso hijo, el proceso padre sale

El proceso padre sale después de crear el proceso hijo, y el proceso hijo se convierte en un proceso huérfano y es adoptado por el primer proceso (proceso de inicio), y el hijo entra en segundo plano para ejecutarse

pid = fork();
if(pid > 0){
    
    
	exit(0);	//父进程退出
}
2.2 El proceso hijo crea una nueva sesión
  • Grupo de procesos: es una colección de uno o más procesos. Está representado de forma única por el ID del grupo de procesos. Además del ID de proceso (PID), el grupo de procesos también es un atributo necesario de un proceso. Cada grupo de procesos tiene un proceso líder de grupo cuyo número de proceso es igual al ID del grupo de procesos, y el ID del grupo de procesos no se verá afectado por la salida del proceso líder del grupo.
  • Período de sesión: una colección de uno o más grupos de procesos. Una sesión comienza cuando se abre el terminal y finaliza cuando se cierra el terminal. El primer proceso de la sesión se convierte en el líder de la sesión. Durante este período, todos los procesos ejecutados por el usuario pertenecen a este período de sesión, y la relación entre ellos se muestra en la siguiente figura.

La relación entre el grupo de procesos y el período de sesión.
La función utilizada en este paso es setsid (), que se utiliza para crear una nueva sesión y actuar como líder de la sesión. Hay tres funciones: liberar el proceso del control de la sesión original, liberar el proceso del control del grupo de procesos original, liberar el proceso del control del terminal de control original;

/*****setsid()函数*****/
函数原型: pid_t setsid(void)
函数返回值:成功返回该进程组ID;失败返回-1

El proceso hijo crea una nueva sesión y el proceso hijo se convierte en el nuevo líder de la sesión, eliminando el terminal original.

if(setsid() < 0){
    
    
	exit(-1);
}
2.3 Cambiar el directorio actual

El proceso hijo hereda el directorio de trabajo actual del proceso padre. Dado que el demonio siempre se ejecuta en segundo plano, su directorio de trabajo no se puede desinstalar, por lo que es necesario cambiar el directorio de trabajo. Por lo general, deje que el directorio raíz sea el directorio de trabajo actual del demonio.
Utilice la función chdir (), como chdir ("/ tmp")

2.4 Restablecer máscara de permiso de archivo

El proceso hijo hereda la máscara de permiso de archivo del proceso padre, lo que tiene un cierto impacto en el uso de archivos por parte del proceso hijo. Por lo tanto, establecer la máscara de permiso de archivo en 0 puede mejorar la flexibilidad del demonio.
Utilice la función umask (), como umask (0)

2.5 Cerrar el descriptor de archivo

El proceso hijo hereda algunos de los archivos abiertos del proceso padre. Es posible que el demonio nunca acceda a estos archivos abiertos, pero también ocupan recursos del sistema y también pueden provocar que el sistema de archivos donde se encuentran no se pueda descargar.
Utilice la función close (), el siguiente ejemplo

int num;
num = getdtablesize();	//获取当前进程文件描述符表大小
for(i = 0;i < num;i++){
    
    
	close(i);
}

Crea una instancia de demonio

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/stat.h>

int main()
{
    
    
	pid_t pid;
	int i, fd;
	char *buf = "This is a daemon\n";

	pid = fork();	//第一步
	if(pid < 0){
    
    
		printf("Error fork\n");
		exit(1);
	}
	else if(pid > 0){
    
    
		exit(0);	//父进程退出
	}

	setsid();	//第二步
	chdir("/tmp");	//第三步
	umask(0);	//第四步
	for(i = 0;i < getdtablesize();i++){
    
    	  //第五步
		close(i);
	}
	/*这时创建完守护进程,以下开始正式进入守护进程工作*/
	while(1){
    
    
		if((fd = open("daemon.log",O_CREAT|O_WRONLY|O_TRUNC,0600)) < 0){
    
    
			printf("OPen file error\n");
			exit(1);
		}
		write(fd,buf,strlen(buf));
		close(fd);
		sleep(2);
	}
	exit(0);
}

Compile y ejecute, use tail -f /tmp/daemon.log para ver que las cadenas se escribirán en el archivo correspondiente cada 2 segundos. Utilice el comando ps para ver que el proceso se está ejecutando en segundo plano.

linux@linux-virtual-machine:~/andy/proc$ tail -f /tmp/daemon.log
This is a daemon
...
linux@linux-virtual-machine:~/andy/proc$ ps -ef|grep daemon
linux     3184  2001  0 13:01 ?        00:00:00 ./daemon
linux     3247  2001  0 13:04 ?        00:00:00 ./daemon
linux     3250  2667  0 13:05 pts/0    00:00:00 grep --color=auto daemon

3. Manejo de errores del demonio

Dado que el proceso del demonio está completamente separado del terminal de control, no puede enviar información de error al terminal de control como un proceso normal. En general, el proceso del demonio se depura mediante el servicio syslog y la información de error del programa se ingresa en el archivo de registro del sistema (como "/ var / log / messages"), de modo que el problema del programa se pueda ver intuitivamente.
syslog es un servicio de administración de registros del sistema en Linux, mantenido por el proceso daemon syslogd. El daemon lee un archivo de configuración "/etc/syslog.conf" cuando se inicia, y el archivo siente dónde se enviarán los diferentes tipos de mensajes. Por ejemplo, los mensajes de emergencia pueden enviarse al administrador del sistema y mostrarse en la consola, mientras que los mensajes de advertencia se pueden grabar en un archivo.
El mecanismo proporciona tres funciones relacionadas con syslog, a saber:
openlog (): abre una conexión al servicio de registro del sistema
syslog (): escribe mensajes en el archivo de registro y especifica la prioridad del mensaje, el formato de salida del mensaje, etc.
closelog () : Cierra la conexión al servicio de registro del sistema

/************openlog()函数************/
函数原型:void openlog(char *ident, int option, int facility)
传入值:ident 要向每个消息加入的字符串,通常为程序的名称
	   option 
	   -->LOG_CONS 如果消息无法送到系统日志服务,则直接输出到系统控制终端
	   -->LOG_NDELAY 立即打开系统日志服务的连接,一般直接发送第一条消息时才打开连接
	   -->LOG_PERROR 将消息也同时送到stderr-->LOG_PID 在每条消息中包含进程的PID
	   facility 指定程序发送的消息类型
	   -->LOG_AUTHPRIV 安全/授权信息
	   -->LOG_CRON 时间守护进程(cron及at)
	   -->LOG_DAEMON 其他守护进程
	   -->LOG_KERN 内核信息
	   -->LOG_LOCAL[0~7] 保留
	   -->LOG_LPR 行打印机子系统
	   -->LOG_MAIL 邮件子系统
	   -->LOG_NEWS 新闻子系统
	   -->LOG_SYSLOG syslogd内部所产生的信息
	   -->LOG_USER 一般使用者等级信息
	   -->LOG_UUCP UUCP子系统
/************syslog()函数************/
函数原型:void syslog(int priority, char *format,...)
传入值:priority 
	   -->LOG_EMERG 系统无法使用
	   -->LOG_ALERT 需要立即采取措施
	   -->LOG_CRIT 有重要情况发生
	   -->LOG_ERR 有错误发生
	   -->LOG_WARNING 有警告发生
	   -->LOG_NOTICE 正常情况,但也是重要情况
	   -->LOG_INFO 信息消息
	   -->LOG_DEBUG 调试信息
	   format 以字符串指针的形式表示输出的格式,类似于printf中的格式
/************closelog()函数************/
函数原型:void closelog(void)

Supongo que te gusta

Origin blog.csdn.net/Chuangke_Andy/article/details/108303020
Recomendado
Clasificación