2010-09-14 12 views
8

Ya leí la página man de la familia de funciones pidfile. Pero realmente no lo entiendo ¿Cuál es el uso correcto? ¿Hay algún ejemplo más elaborado disponible? Creo que entiendo pidfile_open. ¿Pero cuándo debo llamar al pidfile_write y al prdfile_close? ¿De qué proceso? ¿Padre o hijo? ¿Qué parámetros tengo que pasar a esas funciones? Creo que carezco de algunos fundamentos de * nix, supongo.¿Cómo usar la biblioteca de archivos pid correctamente?

Actualización:

Abajo puedes ver el ejemplo del hombre pidfile. ¿Por qué se bifurcan dos veces? ¿Por qué pidfile_close? Cuando llamo a pidfile_close, puedo iniciar otro daemon. ¿No es eso no deseado?

struct pidfh *pfh; 
pid_t otherpid, childpid; 

pfh = pidfile_open("/var/run/daemon.pid", 0600, &otherpid); 
if (pfh == NULL) { 
     if (errno == EEXIST) { 
       errx(EXIT_FAILURE, "Daemon already running, pid: %jd.", 
        (intmax_t)otherpid); 
     } 
     /* If we cannot create pidfile from other reasons, only warn. */ 
     warn("Cannot open or create pidfile"); 
} 

if (daemon(0, 0) == -1) { 
     warn("Cannot daemonize"); 
     pidfile_remove(pfh); 
     exit(EXIT_FAILURE); 
} 

pidfile_write(pfh); 

for (;;) { 
     /* Do work. */ 
     childpid = fork(); 
     switch (childpid) { 
     case -1: 
       syslog(LOG_ERR, "Cannot fork(): %s.", strerror(errno)); 
       break; 
     case 0: 
       pidfile_close(pfh); 
       /* Do child work. */ 
       break; 
     default: 
       syslog(LOG_INFO, "Child %jd started.", (intmax_t)childpid); 
       break; 
     } 
} 

pidfile_remove(pfh); 
exit(EXIT_SUCCESS); 
+0

¿La página de manual que está viendo tiene una sección de "ejemplo"? El BSD sí lo hace, lo que ilustra bastante bien el uso común. Consulte http://fuse4bsd.creo.hu/localcgi/man-cgi.cgi?pidfile+3, consulte la sección "ejemplo". –

+0

@Tim, la página man contiene un ejemplo pero tengo problemas para aplicarlo a mi código daemon. Mi daemon está estructurado de manera diferente. Por ejemplo, no uso la función daemon (3). –

Respuesta

5

El problema es que se quiere dar un mensaje de error antes de que se genera el demonio, y que sabe que el archivo PID después de que el demonio se genera.

Por lo tanto, normalmente hace el pidfile_open antes de la bifurcación, lo que le da la posibilidad de dar un mensaje de error. Después de bifurcar, conoce el archivo pidfile y puede hacer pidfile_write.

+0

¿Por qué el tenedor? daemon() se bifurca, ¿no? ¿Por qué un segundo tenedor? –

+0

Sí, daemon() se bifurca. Me refiero a la bifurcación, no hay una segunda bifurcación. Entonces llama a pidfile_open(), daemon(), pidfile_write(), pidfile_close(). De esta forma, puede generar cualquier error desde pidfile_open() al terminal (antes de separarlo) y escribir el PID del hijo, que solo se conoce después de llamar a daemon(). – Sjoerd

+0

Oh, pensé que querías decir el código de ejemplo de man pidfile. Porque hay un "segundo" tenedor hecho después del daemon(). ¿Sabes por qué? –

1

Hace el archivo pidfile_open (3) antes de pasar al fondo, por lo que puede informar de inmediato cualquier problema. No escribe PID todavía, porque su PID cambiará después de Daemon (3). pidfile_open (3) solo bloquea el archivo pidfile. Después de daemon (3) puede llamar a pidfile_write (3) ya que ahora tiene su PID final (daemon (3) se bifurca internamente). En el proceso principal no puede llamar a pidfile_close (3), porque esta es la idea completa: manteniendo el archivo de identificación abierto y bloqueado, haga saber a los demás que todavía está vivo. La segunda horquilla es totalmente opcional. Ilustra el comportamiento común que los daemons generan en los procesos niño/trabajador. Si no los usa, no necesita esta horquilla(). Esta bifurcación() está allí solo para mostrar que en dicho proceso de trabajo debe cerrar el archivo pid, por lo que solo lo mantiene abierto y bloqueado por el proceso principal y no por el niño.

Cuestiones relacionadas