2010-09-14 11 views
8

Ich habe bereits die man-Seite der Pidfile-Familie gelesen. Aber ich verstehe es nicht wirklich. Was ist die richtige Verwendung? Gibt es ein ausführlicheres Beispiel? Ich glaube ich verstehe pidfile_open. Aber wann sollte ich pidfile_write und prdfile_close anrufen? Aus welchem ​​Prozess? Eltern oder Kind? Welche Parameter muss ich an diese Funktionen übergeben? Mir fehlen wahrscheinlich einige * nix-Grundlagen.Wie verwende ich die PID-Datei-Bibliothek richtig?

Update:

Weiter unten finden Sie das Beispiel von Mann pidfile sehen. Warum verzweigen sie sich zweimal? Warum pidfile_close? Wenn ich pidfile_close aufruft, kann ich einen anderen Daemon starten. Ist das nicht unerwünscht?

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

Hat die Man-Seite, die Sie sehen, einen "Beispiel" -Abschnitt? Das BSD tut man, was den allgemeinen Gebrauch recht gut veranschaulicht. Siehe http://fuse4bsd.creo.hu/localcgi/man-cgi.cgi?pidfile+3, sieh dir den Abschnitt "Beispiel" an. –

+0

@Tim, die man-Seite enthält ein Beispiel, aber ich habe Probleme, es auf meinen Daemon-Code anzuwenden. Mein Daemon ist anders strukturiert. Zum Beispiel verwende ich nicht die Funktion daemon (3). –

Antwort

5

Das Problem ist, dass Sie eine Fehlermeldung geben möchten, bevor der Dämon hervorgebracht wird, und dass Sie die PID-Datei kennen, nachdem der Dämon hervorgebracht wird.

Sie tun also normalerweise die pidfile_open vor der Gabelung, die Ihnen die Möglichkeit gibt, eine Fehlermeldung zu geben. Nachdem du gegabelt hast, kennst du die Pidfile und du kannst pidfile_write machen.

+0

Warum die Gabel überhaupt? Daemon() Gabeln, nicht wahr? Warum eine zweite Gabel? –

+0

Ja, daemon() Gabeln. Ich meinte diese Gabel, es gibt keine zweite Gabel. Also rufen Sie pidfile_open(), daemon(), pidfile_write(), pidfile_close() auf. Auf diese Weise können Sie alle Fehler von pidfile_open() an das Terminal ausgeben (bevor es losgelöst wird) und die PID des Kinds schreiben, die nur nach dem Aufruf von daemon() bekannt ist. – Sjoerd

+0

Oh, ich dachte, du meintest den Beispielcode von man pidfile. Weil dort nach dem daemon() eine "zweite" Gabelung gemacht wird. Weißt du, warum? –

1

Sie tun die Pidfile_open (3), bevor Sie in den Hintergrund gehen, so dass Sie sofort Probleme melden können. Sie schreiben PID noch nicht, weil sich Ihre PID nach dem Daemon (3) ändert. pidfile_open (3) sperrt nur die PID-Datei. Nach dem Daemon (3) kannst du pidfile_write (3) aufrufen, da du nun deine letzte PID hast (daemon (3) gibt intern Forks aus). Im Hauptprozess können Sie pidfile_close (3) nicht aufrufen, da dies die ganze Idee ist - indem Sie die Pidfile offen und gesperrt halten, lassen Sie andere wissen, dass Sie noch am Leben sind. Die zweite Gabel ist völlig optional. Es veranschaulicht gängiges Verhalten, dass Daemons Child/Worker-Prozesse hervorbringen. Wenn Sie sie nicht benutzen, brauchen Sie diese Gabel nicht(). Mit diesem fork() soll nur angezeigt werden, dass in einem solchen Worker-Prozess die PID-Datei geschlossen werden sollte. Sie wird also nur vom Hauptprozess und nicht vom Kind geöffnet und gesperrt.

Verwandte Themen