"watchdog" software timer

Stigmer

Grünschnabel
OS: WinXP
IDE: VS C++ 2008 Express

----------------------------------------------------------

Hallo,

mein Ziel ist es, eine Art Watchdogtimer zu realisieren, welcher bei Ablauf für den geregelten Programmabbruch sorgt, sollte das Programm nicht zu einer gegebenen Zeit fertig sein.

Derzeit habe ich 2 Sorgen. Stand der Dinge ist:

Code:
UINT_PTR timerID = 1;

SetConsoleTitle("MyProg");

... // anderer Programmcode

HWND hwnd = FindWindow(NULL, "MyProg");

SetTimer(hwnd, timerID, 7000, NULL);

if (hwnd != NULL)
printf("\nDa ist ja mein Handle. :)");

----------------------------------------------------------

1. Wie kann ich jetzt das Event einfangen, welches durch das Ablaufen des Timers ausgelöst wird? Könnt ihr mir da ein Codebeispiel liefern?

- Kann man das Ganze so gestalten, dass ein solches Event abgefangen werden kann ohne darauf zu pollen und damit das restliche Programm lahm zu legen? (diese Frage ist eher nebensächlich, da das Programm nach Ablauf des Timers längst fertig ist, also auch die Timerungenauigkeit ist da nicht entscheidend.)

2. Wenn sich das Programm aufhängen sollte, ist auch mein Timer fest gefahren, oder? (auch diese Frage ist nebensächlich)

----------------------------------------------------------

Ich freue mich auf Antworten und bin für jede gut gemeinte Hilfe dankbar. Was ich in den anderen Themen dieses Forums zum Thema "timer" gefunden habe, lässt mich hoffen. :) Leider bin ich daraus bisher nicht ganz schlau geworden bzw. trafen die Beispiele nicht ganz meinen Fall.
 
Zuletzt bearbeitet:

MCoder

Erfahrenes Mitglied
Schaue dir in der MSDN nochmal die Beschreibung zur SetTimer-Funktion an. Der letzte Parameter (den du mit NULL belegt hast) sollte einen Zeiger zu einer Callback-Funktion erhalten, welche bei jedem Timerevent aufgerufen wird.

Gruß
MCoder
 

Stigmer

Grünschnabel
Das Ganze habe ich schon überflogen, mir aber beim Hinweis auf die "TimerProc" Funktion ein wenig Angst einjagen lassen.. Vielleicht unnötiger Weise?!

Reicht da ein Zeiger auf eine gewöhnliche Funktion?

Gruß
Steffen
 
Zuletzt bearbeitet:

Stigmer

Grünschnabel
Mein vorheriger Beitrag ist hiermit outdated.
---------------------------------------------------------------------
Ich habe jetzt folgende Änderung vorgenommen:

Code:
SetTimer(hwnd, timerID, 2000, (TIMERPROC)timer_event);

wobei die Funktion timer_event nichts anderes macht als ne printf Ausgabe.. Leider tut sie mir diesen Gefallen nicht. Sieht jemand den Fehler? Braucht ihr weitere Infos?

Gruß
Steffen
 

Stigmer

Grünschnabel
Ich bin´s nochmal. Nach erneuter Konsultation von MSDN hab ich mir mal den Return Value von SetTimer angeschaut..

C++:
int timer_return;
int x = 1;
UINT_PTR timerID = x; // = NULL ergibt den selben Fehler
HWND hwnd = FindWindow(NULL, "MyProg");

timer_return = SetTimer(hwnd, timerID, 7000, (TIMERPROC)timer_event);

if (hwnd != NULL)
	printf("\nDa ist ja mein Handle. :) SetTimer Return ist übrigens %d\n", timer_return);

if (timer_return == 0)
	printf("\nErrorCode: %d\n", GetLastError());

SetTimer gibt bei mir 0 zurück, also einen Fehler. GetLastError wirft '5' aus, was laut MSDN (http://msdn.microsoft.com/en-us/library/ms681382(VS.85).aspx) "access denied" bedeutet.. Jetzt bin ich völlig verwirrt.. :(
 
Zuletzt bearbeitet von einem Moderator:

MCoder

Erfahrenes Mitglied
Hallo,

hab mich gerade nochmal schlau gemacht: In Konsolenanwendungen funktioniert SetTimer() leider nicht, weil das Ganze über Windows-Messages (WM_TIMER) läuft und dafür eine entsprechende Nachrichtenschleife gebraucht wird.
Da du ja keine periodische Geschichte benötigst, könntest du alternativ einen Thread im Hintergrund laufen lassen, der am Ende der vorgegebenen Zeit das Programm beendet. Hier mal ein einfaches Beispiel:
C++:
#include <process.h>
#include <iostream>

unsigned int _stdcall ThreadFunction(void *);

int main()
{
    unsigned int nThreadAddress;

    _beginthreadex( 0,
                    0,
                    ThreadFunction,
                    0,
                    0,
                    &nThreadAddress );

    while( 1 )
    {
        std::cout << "irgendwas tun" << std::endl;
        Sleep(10); // Etwas Zeit abgeben, damit der andere Thread nicht verhungert
    }
        
    return 0;
}

unsigned int _stdcall ThreadFunction(void *)
{
    Sleep(5000); // Der ganze Spuk dauert 5 Sekunden
    exit(0);    
}
Gruß
MCoder
 

Stigmer

Grünschnabel
Guten Morgen,

hoffte mich um Threads herumdrücken zu können, aber dein Beispiel (vielen dank dafür!) scheint doch recht handhabbar. :) Ich versuch mal mein Glück.

Gruß
Steffen
 

Stigmer

Grünschnabel
Hi,

ich habe mich letztendlich eines Workarounds bedient. Per clock() den kritischen Abschnitt zeitlich bemessen und bei zu hoher Verzögerung das Programm entsprechend beendet.

Kann man hier User bewerten? ;)

Besten dank nochmal!