watchdog



  • Die musst dir wohl selber schreiben.

    Absolutes Trivialbeispiel ( ungetestet)

    Globale Variable
    
    unsigned int Ich_lebe_noch=0;
    unsigned int Exit_thread=0;
    
    void Setze_Ich_lebe_noch(void)
    {
    Ich_lebe_noch=1;
    }
    
    void Setze_Exit_thread(void)
    {
    Exit_thread=1;
    }
    
    watdog thread
    
    void watch (pvoid p)
    {
    Setze_Ich_lebe_noch();
     for(;;)
      {
      if (1==Exit_thread)
        break;
      if (0!=Ich_lebe_noch)
        {
        Ich_lebe_noch=0;
          sleep(1000);
        }
      else
       {
       // Bullsch...
       exit(-1)  // katastrophaler Fehler
       }
      }
    // hier Thread verlassen
    }
    

    Im laufende Programm muss jetzt dafür gesorgt werden, das innerhalb von 800 mSec die Funktion Setze_Ich_lebe_noch aufgerufen wird. Dadurch das die Funktion Setze_Ich_lebe_noch in watch for der For schleife aufgerufen wird hat man erst mal 800 mSec Zeit für andere Aufgaben.

    Die 800 mSec ist bei Sleep(1000) mit ABsicht gewählt um auch Betriebssystem Zeitjitter ziemlich unter Kontrolle zu halten. Man sollte nie den Abbruchwert und die Zeit für das setzen dicht beieinander wählen, das führt nur zu Strss.

    P.S. Der Code oben ist nur ein Anhalt für das Verfahren.



  • Wo gibt's in (ANSI)-C einen Watchdog? Oder hab ich was übersehen?

    Das 800-ms-teil ist relativ gefährlich, da es unter Windows keine Garantien für Latenzzeiten gibt.

    Eine sinnvolle Implementation müßte wenigstens einen zusätzlichen thread auf niedrigster priorität, um zu unterscheiden, ob die Anwendung hängt oder das System nur beschäftigt ist.

    Das löst aber immer noch nicht die Frage, ob die Anwendung nur mit einer längeren berechnung beschäftigt ist, oder tatsächlich "tot".



  • Dies ist ein Trivialbeispiel (oben angeführt) wie ich mit der WinApi (Sleep, threads) und C so etwas realisieren kann,
    Auch "professionelle " Watchdog Lösungen gehen davon aus das der laufende Process innnerhalb einer definierten Zeit die Watchdog zurücksetzt.

    Apropos Lange Rechnung. Solche Fuinktionen müssen den Watchdog Aufruf in regelmäßigen Zeitabständen selber
    duchführen.

    Definitiv falsch ist einen weiteren Thread aufzusetzen, welcher in regelmäßigen Zeitabständen den Watchdog
    zurücksetzt.

    EIn Programm ist dann als tot definiert wenn es den Watchdog nicht rechtzeitig zurücksetzt.

    Die 800 mSec ist bei Sleep(1000) mit ABsicht gewählt um auch Betriebssystem Zeitjitter ziemlich unter Kontrolle zu halten. Man sollte nie den Abbruchwert und die Zeit für das setzen dicht beieinander wählen, das führt nur zu Strss.

    Mit deiner Zeitkritik hast du vielleicht recht, Vielleicht sollte man mehr als 20% Jitter zulassen.
    Das sollte man aber ausprobieren. Wenn ein System eine Watchdog will muß man sich eh mit dem Zeitverhalten des Systems auseinandersetzten udn kann dann eine vernünftige Relation wählen.

    😃 WINAPI Forum :p



  • OK, ich dachte Marc kennt einen im C standard definierten Watchdog von dem ich noch nix gehört hab 🤡

    PAD schrieb:

    EIn Programm ist dann als tot definiert wenn es den Watchdog nicht rechtzeitig zurücksetzt.

    Ei weh...
    Ich denke nicht, das Jitter zwischen Watchdog und App das Problem ist.
    Problematisch wird's dann, wenn ein Thread mit hoher Priorität für eine Sekunde beschäftigt ist, und dann der Watchdog vor der App an die Reihe kommt. Ergebnis: Eine Anwendung, die "Auf den Desktop abstürzt", wenn der Rechner mal ein bisserl rödelt. Die Prio des Watchdogs runterzusetzen hilft, glaub ich, nur unterm NT Kernel, Win9x fügt noch einen random-wert in den Scheduler ein, um bestimmte deadlocks zu lösen (kann mich aber auch irren)

    Der Low-Priority Thread war nicht zum rücksetzen des Watchdog gedcht, eher zum abschießen: Wen der LP thread genug Rechenzeit bekommt, die zu überwachende App den Watchdog aber nicht zurücksetzt, ist wohl wirklich was faul. Eigentlich kann man den Watchdog gleich im LP thread laufen lassen - aber nicht it Sleep sondern z.B. mit (asgemessenen) NOP's. Das funktioniert vielleicht sogar wirklich...



  • Die Frage ist was will er ereichen. So wie er es schildert wäre auch eine 10 Sekunden Timeout und eine 100 mSec Rücksetzzeit völlig ausreichend. Sein Ziel scheint zu sein, das wenn sein Programm spinnt er nicht den Taskmanage zum Abschießen nehmen muß.

    Ich dachte da eher an System in die Dinge in gewissen Zeiten erledigen müssen (softest realtime as possible jitter ca 300 mSec), dann dürfen solche Killerapplikation die ohne meine Planung an ihren eigenen Prioritäten drehen und sich Rechenzeit ohne Ende abgreifen eh nicht laufen. Nich mal eben Word neben einer watchdog Applikation laufen lassen.

    Das hatte ich bei deiner Fragestellung nicht vermutet, hatte nur die Sorge das dritte auf so eine Schnapsidee kommen.

    Watchdog mit low Priority, wohl eher das Gegenteil, im Prinzip ist der wichtiger als die Applikation. Nicht umsonst wird in kritischen Systemen der Watchdog in HW ausgeführt und geht meistens direkt auf den Reset.
    Schon meine gleichpriorisiere Lösung ist aus den von dir genannten Gründen (High Prio SW) in diesem Sinne gefährlich, weil sie sich um die gleiche Zeitscheibe mit der Appl streitet.



  • stimmt... wenn die App in 'ner Endlosschleife hängt statt in einem Deadlock o.ä., dann würde mein Watchdog nicht anspringen. Hm....



  • hallo leute

    vielen dank für eure beiträge... ich möchte noch kurz erwähnen, dass ich keine feste zeit setzen kann, denn sobald ich über die comschnittstelle etwas auslese, kann das von 10 sec bis zu 2 minuten dauern...

    PAD schrieb:

    Die Frage ist was will er ereichen. So wie er es schildert wäre auch eine 10 Sekunden Timeout und eine 100 mSec Rücksetzzeit völlig ausreichend. Sein Ziel scheint zu sein, das wenn sein Programm spinnt er nicht den Taskmanage zum Abschießen nehmen muß.

    genau das wäre eigentlich meine idee, es soll erst reagieren wenn 10 sec nichts passiert ist, also wenn der taskmanager meldet dass er keine rückmeldung bekommt..

    ciao



  • Wenn du soetwas machen mußt, kannst du bei jedem Reset des Watchdogs diesem mitteilen wie lange er das nächste mal warten soll.

    Aber ob dein Konzept sinnvoll ist, ich weis...

    Erzähl mal was willst du eigentlich für ein Problem Lösen.
    Serielle Schnittstelle haben timeouts, man kann das Lesen in einen eigenen thread packen und das Ergebnis melden. Dann sind solche Konstrukte meistens nicht nötig



  • oder mit FILE_FLAG_OVERLAPPED arbeiten 🙂



  • was ist FILE_FLAG_OVERLAPPED?



  • Ein Flag für CreateFile:

    MSDN-Library zu <a href= schrieb:

    CreateFile">Instructs the system to initialize the object, so that operations that take a significant amount of time to process return ERROR_IO_PENDING. When the operation is finished, the specified event is set to the signaled state.
    When you specify FILE_FLAG_OVERLAPPED, the file read and write functions must specify an OVERLAPPED structure. That is, when FILE_FLAG_OVERLAPPED is specified, an application must perform overlapped reading and writing.

    When FILE_FLAG_OVERLAPPED is specified, the system does not maintain the file pointer. The file position must be passed as part of the lpOverlapped parameter (pointing to an OVERLAPPED structure) to the file read and write functions.

    This flag also enables more than one operation to be performed simultaneously with the handle (a simultaneous read and write operation, for example).



  • ok, dass habe ich auch schon gelesen...
    die meinung wäre wohl, dass ich beim createfile zum öffnen der schnittstelle mein flag so setze, aber ich arbeite mit einer nicht (!!!) overlapped struktur... also wird das wohl nichts, habe es schon getestet, aber dann funktioniert gar nichts mehr...
    muss ich wirklich einen eigenen thread machen?
    irgendwie klingt das ein wenig kompliziert für mich. gibt es nicht eine alternative? irgend eine message die vom system oder vom programm kommt und anzeigt dass vom programm her keine rückmeldung kommt? dann könnte ich dem programm sagen dass es den laufenden prozess beenden soll und sich selber wieder neu lädt und eine fehlermeldung ausgibt..

    vielleicht bin ich auch nur unfähig..



  • Und warum verwendest du nicht einfach eine OVERLAPPED-Struktur 😕



  • weil ich meinen port exklusiv holen muss....



  • marc_ch schrieb:

    weil ich meinen port exklusiv holen muss....

    Flenders spricht von den Flags und der OVERLAPPED-Struktur, nicht vom Share-Mode.



  • ich weiss schon dass er von flags spricht, aber die sehr wohl einen einfluss
    auf den share-mode. wenn die struktur overlapped ist kannst du keine ports mehr exklusiv holen.. stimmt doch oder?

    sorry, war vielleicht ein wenig kurz...



  • marc_ch schrieb:

    stimmt doch oder?

    Nein.



  • Threads hören sich kompliziert sind es aber nicht.

    Im Hauptprogramm schreibt man _beginthread(....),
    und anstelle von return schreibst du einfach _endthread();
    Das ist alles was du für deine Fall brauchst.

    #define ON 1
    #define OFF 0
    
    volatile int GlobalWatchDog=ON;
    volatile int GlobalEndThread=OFF;
    
     void TrivialWatchDog( PVOID VOID);
    
    int main()
    {
    .....
      // Sobald sie Watchdogüberwachung beginnen soll
      GlobalWatchDog++;
      _beginthread( TrivialWatchDog, 0, 0 );
    .....
      // in Regelmäßigen Abständen im Hautpprogramm dann ein (alle 600 mSec)
     GlobalWatchDog++;
    .......
      // Sobald die WatchdogÜberwachung enden soll
      GlobalEndThread=ON;
    ...
    return 0;
    }
    
    Die Threadfunktion sieht dann wie folgt aus.
    
    void TrivialWatchDog( PVOID VOID)
    {
    int i;
    if(OFF!=GlobalWatchDog)  // Programm lebt noch
     {
      GlobalWatchDog=OFF;
      for (i=0;i<20;i++)  
      {
       if (ON==GlobalEndThread)
       _endthread();
       Sleep(50);
      }
     }
     else  // Programm hat sich nicht gerührt
     {
     exit(-1);  // Als Beispiel ein harter Abbruch.
     }
        /* _endthread given to terminate */
    _endthread();
    }
    

    - Für die C++ Profis man kann das auch in eine eigene Klasse packen.
    - Ich weis, der direkte Zugriff auf Globale ist nicht im Sinne der reinen Leere
    - Ich weis, man sollte Globale Minimieren.
    - Ich weis, Accessfunktionen für die Variablen sind sicherer.
    - Die Timeoutzeit sollte man auch variable gestalten
    Aber dann wäre es dreimal so lang geworden und nicht so übersichtlich



  • Die globalen Variablen sollten als volatile gekennzeichnet werden. Außerdem würde ich auf _endthread verzichten und den Thread durch ein einfaches return beenden wollen.



  • Das mit dem volatile habe ich sinnvollerweise korrigiert.

    Aber warum _endthread durch return erstzen??

    ich fände es schon schön wenn die threadfunkrionen sich überhaupt nicht von
    einfachen C-Funktionen unterscheiden, aber in den Büchern wird immer auf
    _endthread hingewiesen


Anmelden zum Antworten