watchdog



  • 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



  • PAD schrieb:

    Aber warum _endthread durch return erstzen??

    Das _endthread würgt den Thread sofort und auf der Stelle ab. In Deinem Beispiel ist das auch kein Problem. Wenn nun aber Klassen dazukommen, werden keine Destruktoren aufgerufen. Und das finde ich bedenklich.

    Wenn Du den Thread einfach auslaufen lässt, funktioniert das wieder. Intern wird dann sowieso _endthread aufgerufen. Ein direkter Aufruf ist überflüssig.



  • Danke für die Information, ist Gott sei Dank in meinem Sinne.

    D.h. für die C-Fraktion ist es unerheblich ob sie return oder _endthread nimmt, für die C++ Fraktion ist es entscheidend das sie mit return arbeitet.

    Da _endthread nicht mehr Leistung als return bietet, sollte man return in beiden Fraktionen nutzen

    Sehe ich das richtig?



  • PAD schrieb:

    Sehe ich das richtig?

    Ja. Man kann sich aber auch in C ganz schnell 'ne Falle bauen:

    void DoSomething(void* pv)
    {
        _endthread();
    }
    
    void ThreadProc(void* pv)
    {
        void* pVoid = malloc(128);
        DoSomething(pVoid);
        free(pVoid);  // hier kommst Du nie an
    
      return;
    }
    

    Also immer schön auf _endthread verzichten. Dann kann auch nichts passieren. 😉



  • Schöne Sache, aber auch andere Statements als free werden genausoweinig ausgeführt.
    Ein thread ist kein Funktionsaufruf sondern der Start eines eigenen Fadens - er kehrt nicht an die Stelle des Aufrufs zurück - , der beim Beenden auch noch ein paar lustige Sync probleme machen kann.

    void DoSomething(void* pv) 
    { 
    Sleep(2000);
    
    pPad[0]=300;
        _endthread(); 
    } 
    
    int* pPad;
    
    int main() 
    { 
     if (0==(pPad = malloc(128)))
      {
       printf("\nmalloc failed\n);
       return -1
      }
    
      _beginthread(DoSomething(pVoid)); 
      Sleep(500);
      free(pPad);  // hier kommst du viel zu früh an
      return 0; 
    }
    

    ´tschuldigung natürlich muß DoSomething als thread aufgerufen werden.



  • Für mich sieht das gerade so aus, als ob du -King- nicht verstanden hast 😉
    DoSomething ist ja nicht die Thread-"Funktion", sondern eine Funktion, die aus den Thread (ThreadFunc) heraus aufgerufen wird.

    Du rufst ganz normal die Funktion DoSomething aus main auf und darin _endthread(); - was für einen Sinn soll das geben 😕



  • flenders schrieb:

    Du rufst ganz normal die Funktion DoSomething aus main auf und darin _endthread(); - was für einen Sinn soll das geben 😕

    Das hat natürlich keinen Sinn. Ich meine aber auch, daß das PAD bekannt ist. Man kann auch nicht einfach _beginthread auf einen Thread aufrufen, den man nicht gestartet hat.

    Er wollte halt auf allgemeine Synchronisations-Probleme hinweiseisen, die es selbstverständlich auch gibt. Im Grunde ist das ein Beispiel für meine Behauptung, daß auch _beginthread verboten gehört. Aber als ich das zum letzten Mal losgeworden bin, wurde mir ans Herz gelegt, mich erstmal mit den Basics zu beschäftigen. Deswegen werde ich jetzt auch nicht näher darauf eingehen.



  • Entschuldigung für den Schreibfehler im Code, ich habe ihn korrigiert.

    @ King Ohne die prügelen zu wollen, will soll man sonst in C multithreaded programmieren?
    Ich brauche dazu eine Funktion des Betriebssystems, welche mir einen Thread startet.


Anmelden zum Antworten