Prüfung, ob weitere Instanz des Programmes läuft



  • Hallo,

    ich habe ein Programm geschrieben, welches ich normalerweise als Dienst laufen lasse. Nun möchte ich die Möglichkeit haben zu prüfen, ob eine zweite Instanz davon läuft. Die eigene PID kann ich ja mit getpid bekommen, aber wie ich bekomme ich eine durch C++ verarbeitbare Liste der PIDs zu dem Programm?

    Viele Grüße
    Holger



  • Viele Dienste speichern ihre PID in /var/run, könntest du evtl. auch machen. Oder du listest alle Prozesse auf und suchst deinen.



  • Die PID speichern hat ein paar Nachteile. Um nur zwei zu nennen, es werden race conditions entstehen und unter Linux möchte man die Möglichkeit haben, einen Dienst mehr als einmal zu starten (natürlich mit unterschiedlichen Konfigurationen). Letzteres lässt sich errechen, indem man den Pfad zur PID-Datei konfigurierbar macht, aber ich würde den einfachereren Weg gehen: Das Programm starten und einfach wieder neustarten, wenn es sich beendet. Das geht zum Beispiel mit http://cr.yp.to/daemontools/supervise.html oder anderen Programmen, es gibt da viel Auswahl.

    Du brauchst nichtmal so ein Programm. Du könntest einfach

    $ while sleep 1; do ./dein_programm; done
    

    oder ähnliches einmal ausführen, dann läuft dein Programm immr.



  • Hallo,

    vielen Dank für Eure Antworten!!

    Ich denke ich sollte ein paar mehr Infos geben:
    Die Software (Steuerung u.a. für unsere Gartenbewässerung), die ich programmiert habe, soll nicht unbedingt immer laufen. Über Kommandozeilenparameter die bei einem unabhängigen Aufruf mitgegeben werden möchte ich auch die Möglichkeit haben, verschiedene Statusinformationen auszugeben (z.B. ob der Automatikmodus eingeschaltet ist, welche durch die Existenz einer Datei in /etc gekennzeichnet ist) aber auch ob der Dienst läuft. Vermutlich ist die Auflistung aller Prozesse (oder gefiltert nach Namen?) und Prüfung, ob es diesen mehr als einmal gibt das Einfachste?. Nur: Wie mache ich das von C++ aus und verarbeite die Ausgabe?

    Viele Grüße
    Holger



  • Duddits schrieb:

    Vermutlich ist die Auflistung aller Prozesse (oder gefiltert nach Namen?) und Prüfung, ob es diesen mehr als einmal gibt das Einfachste?

    Nein, eigentlich ist jede Lösung besser als das. Prozesse nach Namen filtern ist so ziemlich das fehleranfälligste, was es gibt. Dann würde ich eher noch einen PID-File nehmen.



  • Duddits schrieb:

    Nun möchte ich die Möglichkeit haben zu prüfen, ob eine zweite Instanz davon läuft. Die eigene PID kann ich ja mit getpid bekommen, aber wie ich bekomme ich eine durch C++ verarbeitbare Liste der PIDs zu dem Programm?

    Das Problem vieler Anfänger, die für ihr Problem schon ganz genau wissen, wie/womit sie es lösen können.

    Christoph schrieb:

    Duddits schrieb:

    Vermutlich ist die Auflistung aller Prozesse (oder gefiltert nach Namen?) und Prüfung, ob es diesen mehr als einmal gibt das Einfachste?

    Nein, eigentlich ist jede Lösung besser als das. Prozesse nach Namen filtern ist so ziemlich das fehleranfälligste, was es gibt. Dann würde ich eher noch einen PID-File nehmen.

    Wohl wahr. Auch das PID-Dateigefrickel oder gar ein File-Locking ist letztendlich auch nur Schrott. Wenn man schon ein diesbezüglich famoses Betriebssystem zur Verfügung hat, sollte man dieses auch soweit wie möglich die Arbeit machen lassen, und POSIX bietet hierfür z.B. Semaphoren an, kleines Testprogramm:

    #include <stdio.h>
    #include <semaphore.h>
    #include <fcntl.h>
    
    const char *SEMID = "habefertig";
    
    int main()
    {
      sem_t *s = sem_open(SEMID, O_CREAT|O_EXCL);
    
      if(s == SEM_FAILED)
        return perror(SEMID),1; /* ein anderer Prozess mit der gleichen Semaphore war schneller */
    
      getchar();
    
      if( sem_unlink(SEMID) )
        return perror(SEMID),1;
    
      return 0;
    }
    

    Sollte erstmal so laufen, der sem_open-Aufruf ist hier sogar atomar, probiere es mit 2 Unix-Sessions mal aus.
    Semaphoren arbeiten üblicherweise auf Prozessebene, für Threads also unbrauchbar.
    sem_unlink niemals vergessen, d.h. auch im Exceptionfall muss der Aufruf für die SEMID ausgeführt werden!



  • Wutz schrieb:

    Semaphoren arbeiten üblicherweise auf Prozessebene, für Threads also unbrauchbar.

    WTF?
    Semaphoren wirken prozessübergreifend (was ja für deine Anwendung auch notwendig ist),
    dennoch kann man sie auch nutzen um die Threads einer Anwendung zu synchronisieren.
    Gleiches gilt für Mutexe.

    Die einzige Ausnahme sind die Windows-spezifischen Critical Sections, welche nur für Threadsynchronisation verwendet werden können, aber hier geht es ja um Linux.



  • Deutsche Sprache schwere Sprache.


Anmelden zum Antworten