Frage zu C daemon programmierung

robertmk

Normande
Registriert
04.09.07
Beiträge
583
ich habe einen daemon in C geschrieben. Der daemon soll jede volle 5. Minute laufen und dann warten. Also der damon soll z.B. ..., 13:05:00, 13:10:00, 13:15:00, ... einen Befehl ausführen. Wenn ich den daemon starte und dann ihm sage, er soll 5 Minuten schlafen, dann läuft der Befehl zwar alle 5 Minuten, aber nicht exakt .., 05:00, 10:00, ... Gibt es eine Möglichkeit den daemon zu synchronisieren? Oder kann man eine Art Handler für sowas einrichten?

Vielen Dank :)
Robert
 

MacApple

Schöner von Bath
Registriert
05.01.04
Beiträge
3.652
Ich weiß ja nicht, welcher Befehl ausgeführt werden soll, aber vielleicht lässt sich Deine Aufgabe auch mit dem launchd selbst lösen.

MacApple
 

robertmk

Normande
Registriert
04.09.07
Beiträge
583
Hi MacApple,

danke für die Antwort, launchd ist leider keine Lösung für mich. Daran hatte ich auch schon gedacht, aber launchd startet das prog immer wieder komplett. Mein prog soll starten, sich initialisieren, und dann alle 5 minuten arbeiten.

Grüße
Robert
 

below

Purpurroter Cousinot
Registriert
08.10.06
Beiträge
2.858
Mein prog soll starten, sich initialisieren, und dann alle 5 minuten arbeiten.

Dann sitzt Dein Programm die ganze Zeit da und wartet, verbraucht aber trotzdem Resourcen.

Ich würde es auch erstmal versuchen, über launchd zu regeln.

Wenn Du es im Program lösen willst, dann ist es in jedem Fall einfach Mathematik:

Auch hier mache ich wieder anderer Leut's Arbeit, aber was soll's:

delta = 300 - (time(NULL) % 300);

Jetzt kannst Du einfach sleep (3) nehmen, oder -- falls Du CoreFoundation benutzt -- einen Timer in die CFRunLoop hängen. Falls Du Foundation benutzt, kannst Du Dir mit dem Delta einen NSTimer machen.

Alex
 

robertmk

Normande
Registriert
04.09.07
Beiträge
583
Hi Alex,

ja stimmt schon ein daemon verbraucht Ressourcen, aber das ich die Initialisierung jedes mal neu starten muss halte ich auch nicht für so viel besser. Irgendwie muss es ja möglich sein. Wenn ichs nicht hinbekomme, dann kann ich immer noch mal launchd probieren.

Mein prog ist ein ganz einfach command-line C tool! Ich nutze weder CoreFoundation, noch xcode.

Grüße
Robert
 

below

Purpurroter Cousinot
Registriert
08.10.06
Beiträge
2.858
Mein prog ist ein ganz einfach command-line C tool! Ich nutze weder CoreFoundation, noch xcode.

Wie gesagt, dann time(3) und sleep(3) und Mathematik für Programmieranfänger ;)

Aber falls Dein Program nur für den Mac ist, dann kannst Du ja CoreFoundation verwenden. Und selbst wenn nicht, und Du Dich ein wenig unternehmungslustig und missionarisch fühlst, kannst Du ja CF-Lite nutzen.

Alex
 

robertmk

Normande
Registriert
04.09.07
Beiträge
583
Wie gesagt, dann time(3) und sleep(3) und Mathematik für Programmieranfänger ;)
:p

Ich werde jetzt erst mal nen launchd einrichten, damit ich das prog nutzen kann. Vielleicht gibts ja auch noch ne andere Lösung dafür.

Grüße
Robert
 

robertmk

Normande
Registriert
04.09.07
Beiträge
583
Also ich habe jetzt launchd eingerichtet, aber launchd hilft dabei leider auch nicht! launchd kann zwar alle N Sekunden aufgerufen werden, jedoch gilt das immer vom laden der plist. D.h. auch launchd kann nicht genau alle X:00 Minuten ein Programm ausführen.
 

tjp

Altgelds Küchenapfel
Registriert
07.07.04
Beiträge
4.057
Schau Dir mal die getitimer bzw. setitimer Funktionen an. Mit Hilfe eines Signal-Handler kann man damit ziemlich genau das Programm wieder aktivieren und Aktionen ausführen.
 

robertmk

Normande
Registriert
04.09.07
Beiträge
583
Schau Dir mal die getitimer bzw. setitimer Funktionen an. Mit Hilfe eines Signal-Handler kann man damit ziemlich genau das Programm wieder aktivieren und Aktionen ausführen.

Danke werde ich mal tun. Ein bsp hast du nicht zufällig?
 

MacMark

Jakob Lebel
Registriert
01.01.05
Beiträge
4.874
Also ich habe jetzt launchd eingerichtet, aber launchd hilft dabei leider auch nicht! launchd kann zwar alle N Sekunden aufgerufen werden, jedoch gilt das immer vom laden der plist. D.h. auch launchd kann nicht genau alle X:00 Minuten ein Programm ausführen.

Der Zeitpunkt des Ladens der plist hat nichts mit dem Ausführungszeitpunkt des Binaries zu tun. Du brauchst StartCalendarInterval mit den gewünschten Minuten.

Dein Programm muß sich selbst beenden, um erneut aufgerufen zu werden nach dem Intervall.
 

tjp

Altgelds Küchenapfel
Registriert
07.07.04
Beiträge
4.057
Danke werde ich mal tun. Ein bsp hast du nicht zufällig?
Auf die Schnelle, ich hoffe ich habe nichts Wesentliches übersehen.
Code:
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>

#include <unistd.h>
#include <signal.h>
#include <sys/time.h>

void sigHandler (int signo) {
        printf ("Signal received\n");

        return;
}

int main () {
        timeval interval        = {10, 0};
        timeval value           = {10, 0};

        itimerval ivalue = {interval, value};

        int error = setitimer (ITIMER_REAL, &ivalue, 0);
        if (0 != error) {
                printf (strerror(error));

                return EXIT_FAILURE;
        }

        struct sigaction        saction;
        saction.sa_handler = sigHandler;
        sigemptyset (&saction.sa_mask);
        saction.sa_flags = 0;

        error = sigaction (SIGALRM, &saction, 0);

        if (-1 == error)
                return SIG_ERR;

        for (;;) {
                pause();
        }

        return EXIT_SUCCESS;
}
 

robertmk

Normande
Registriert
04.09.07
Beiträge
583
Der Zeitpunkt des Ladens der plist hat nichts mit dem Ausführungszeitpunkt des Binaries zu tun.
Wenn ich StartIntervall nehme schon ;) Bei StartCalendarInterval gibt es leider nicht die Möglichkeit (wie bei cron) alle x Minute einzugeben, d.h. ich muss je nachdem wie oft ich das Prog laufen lassen will 20-60 Einträge (alle 1-5 Minuten) in StartCalendarInterval einfügen. Irgendwie blöd ... und sinnvoll?

@tjp:
Ich habe das Problem mittlerweile mit alarm gelöst :-D Vielen Dank für deinen Code! So funktioniert das natürlich auch.

Grüße
Robert
 

MacMark

Jakob Lebel
Registriert
01.01.05
Beiträge
4.874
Für feste absolute Minutenangaben mußt Du sowohl bei cron als auch bei StartCalendarInterval die Minutenzahlen alle listen.
Für feste relative Minutenangaben nimmst Du StartInterval, was "alle x Minuten" bedeutet. Nur ein Eintrag nötig.
 

robertmk

Normande
Registriert
04.09.07
Beiträge
583
@MacMark:
Ich weiß ja nicht, welches cron du benutzt, aber */1 führt unter cron immer alle Minuten den Befehl aus (z.B. 17:01:00, 17:02:00, ...) egal wann du cron eingerichtet hast! StartIntervall dagegen für den Befehl alle x Minuten nach dem Einrichten durch launchctl aus (z.B. 17:01:23, 17:02:23, ...)

Vielleicht habe ich dich ja nur falsch verstanden ... also genau das verhalten */1 von cron fehlt einfach unter launchd :(
 

MacMark

Jakob Lebel
Registriert
01.01.05
Beiträge
4.874
Setz mal RunAtLoad auf false.

Du redest erst von einem Dämon und dann davon, daß er jede Minute neu gestartet werden soll. Das ist dann kein Dämon, sondern eine Zuckung.

Wenn Du nicht die 60 Einträge machen willst, dann nutz halt den Wildcard mit cron. Der wird von launchd verwaltet und ist per default leer, aber Du kannst ihn füllen.
 

robertmk

Normande
Registriert
04.09.07
Beiträge
583
Setz mal RunAtLoad auf false.
RunAtLoad steht standardmäßig auf false. Auch wenn ich es hinzufüge, beginnt das Intervall immer ab dem Zeitpunkt, von der die plist geladen wird. Sorry, aber hast du launchd schon mal benutzt?

Du redest erst von einem Dämon und dann davon, daß er jede Minute neu gestartet werden soll. Das ist dann kein Dämon, sondern eine Zuckung.
Nö. Ich rede von einem Daemon, der alle volle X Minuten einen Befehl ausführt. Das ein Befehl der durch cron oder launchd ausgeführt wird, kein Daemon ist, versteht sich von selbst. Ist auch mühselig darüber zu reden, wir wissen beide, was ein Daemon ist und was nicht. Lies bitte meinen ersten Post, da steht doch ziemlich deutlich, was ich suche.

Grüße
Robert
 

MacMark

Jakob Lebel
Registriert
01.01.05
Beiträge
4.874
RunAtLoad steht standardmäßig auf false. Auch wenn ich es hinzufüge, beginnt das Intervall immer ab dem Zeitpunkt, von der die plist geladen wird. Sorry, aber hast du launchd schon mal benutzt?


Nö. Ich rede von einem Daemon, der alle volle X Minuten einen Befehl ausführt. Das ein Befehl der durch cron oder launchd ausgeführt wird, kein Daemon ist, versteht sich von selbst. Ist auch mühselig darüber zu reden, wir wissen beide, was ein Daemon ist und was nicht. Lies bitte meinen ersten Post, da steht doch ziemlich deutlich, was ich suche.

Grüße
Robert

Hätte ja sein können, daß Du es auf true hast. Hatte mich über die krummen Sekunden gewundert. Dann setz ihn halt auf true und lade die plist manuell zur gewünschten Zeit :p

Wenn es Dir nicht auf die Periode, sondern die Startzeit ankommt, dann nutze halt StartCalendarInterval. Das ist immun ;)

Ein Befehl, der durch launchd ausgeführt wird, ist kein Dämon? Besonders die, die in den diversen LaunchDaemons-Verzeichnissen liegen? :cool:

Ob ich launchd *schonmal* benutzt habe? Du kennst mich nicht? Bist Du neu hier? Lad Dir ein paar Praxisbeispiele von meiner Homepage :-* Dann frag nochmal ;)

Dein Eingangsposting sucht einen Dämon, der alle 5 Minuten Stehaufmännchen spielt. Das ist nicht die Aufgabe für einen Dämon.
Laß das Ding durchlaufen, mach x-Minuten-sleeps dabei. Das System wirft Dich dann zur Not aus dem Speicher, falls er benötigt wird, während Du rum-idelst. Und CPU kostet ein sleep ebenfalls nicht.
Ein ständiges Neuanlegen und Wegräumen eines immer wieder gestarteten Prozesses kostet viel mehr als ihn einmal zu starten und pennen zu lassen. Man sollte nicht versuchen, mit einer App das OS nachzubauen. Das können die besser. :oops:
 

robertmk

Normande
Registriert
04.09.07
Beiträge
583
Hätte ja sein können, daß Du es auf true hast. Hatte mich über die krummen Sekunden gewundert. Dann setz ihn halt auf true und lade die plist manuell zur gewünschten Zeit :p
Das ist nicht dein ernst! Und bei einem Neustart, soll ich dann meine plist auch manuell starten? Das ist ein wirklich intelligenter Vorschlag.

Wenn es Dir nicht auf die Periode, sondern die Startzeit ankommt, dann nutze halt StartCalendarInterval. Das ist immun ;)
Ok du hast mein Eingangsposting nicht verstanden., ich erklärs dir nochmal: Ich will einen Daemon haben, der immer zur VOLLEN Minute einen Befehel/Code ausführt. Das Prog soll nicht dauernd neu gestartet werden. Mein Problem ist weder die Startzeit noch das Intervall.

Ein Befehl, der durch launchd ausgeführt wird, ist kein Dämon? Besonders die, die in den diversen LaunchDaemons-Verzeichnissen liegen? :cool:
Ist nur Definitionssache. Sorry, aber hast du auch ein paar Lösungvorschläge oder willst du mich nur belehren?

Ob ich launchd *schonmal* benutzt habe? Du kennst mich nicht? Bist Du neu hier? Lad Dir ein paar Praxisbeispiele von meiner Homepage :-* Dann frag nochmal ;)
Keine Ahnung was du für eine HP hast! Wenn du launchd benutzt, dann wüsstest du, dass es nicht möglich ist launchd immer zur vollen Minute auszuführen, wie z.B. */1 bei cron! Also entweder willst du wichtig machen, oder du hast null schimmer !?!

Dein Eingangsposting sucht einen Dämon, der alle 5 Minuten Stehaufmännchen spielt. Das ist nicht die Aufgabe für einen Dämon.
Laß das Ding durchlaufen, mach x-Minuten-sleeps dabei. Das System wirft Dich dann zur Not aus dem Speicher, falls er benötigt wird, während Du rum-idelst. Und CPU kostet ein sleep ebenfalls nicht.
Ein ständiges Neuanlegen und Wegräumen eines immer wieder gestarteten Prozesses kostet viel mehr als ihn einmal zu starten und pennen zu lassen. Man sollte nicht versuchen, mit einer App das OS nachzubauen. Das können die besser. :oops:
Super jetzt schreibst du genau das was ich schon in meinem ersten Post geschrieben habe und was ich suche. Was ist jetzt deine Lösung, oder willst du nur zeigen das du was weißt ??? :o_O

Grüße
Robert
 

MacMark

Jakob Lebel
Registriert
01.01.05
Beiträge
4.874
… dass es nicht möglich ist launchd immer zur vollen Minute auszuführen, wie z.B. */1 bei cron! …

Doch: Mit 60 Einträgen für die StartCalendarInterval-Minute. Aber das hatte ich oben bereits geschrieben. :mad:

Wenn Du ein Verzeichnis oder eine Datei überwachen willst, bist Du mit QueueDirectories oder WatchPaths besser dran. :innocent:

---
Vermerk: Er kennt mich wirklich nicht. :cool: