Timer Optimieren
-
Hi,
hab da ma vor einiger zeit mir nen timer geschrieben, und mir is aufgefallen das er während des laufens einen meiner cores voll auslastet. Habt ihr da ne Idee wie man das vielleicht etwas optimieren könnte?
#include <windows.h> #include <vector> class TimerManager{ public: TimerManager(); ~TimerManager(); // in milli secs // lP ist Optional! void AddTimer ( int TimeToWait, void ( *Function ) ( PVOID lParam ), PVOID lParam = NULL ); private: struct Timer{ PVOID lParam; double TimeToWait; void (*Function) ( PVOID lParam ); double StartTime; explicit Timer( int TTW, void (*F)( PVOID ), PVOID lP ):TimeToWait(((double)TTW)/1000),Function(F),lParam(lP),StartTime(0){} }; struct FuncThreads{ HANDLE hThread; bool * bRuns; bool Busy; PVOID lParam; void (*Function) ( PVOID lParam ); unsigned short Suspends; explicit FuncThreads ( HANDLE hT, void (*F)( PVOID ), PVOID lP, bool * R ):Busy(false),bRuns(R),Function(F),lParam(lP),Suspends(0),hThread(hT){} }; std::vector < Timer * >Timers; std::vector < FuncThreads * > ThreadPool; HANDLE hThread; bool Runs; static DWORD WINAPI TimerThread ( PVOID lParam ); static DWORD WINAPI FuncThread ( PVOID lParam ); }; TimerManager::TimerManager():Runs(true),hThread(NULL){ DWORD DUMP; hThread = CreateThread( NULL, NULL, TimerThread, (PVOID)this, NULL, &DUMP ); } TimerManager::~TimerManager(){ Runs = false; if ( hThread != NULL ){ DWORD ExitCode; GetExitCodeThread(hThread,&ExitCode); TerminateThread(hThread,ExitCode); CloseHandle(hThread); } for ( std::vector < FuncThreads * >::iterator It = ThreadPool.begin(); It < ThreadPool.end(); It++ ){ DWORD ExitCode; GetExitCodeThread((*It)->hThread,&ExitCode); TerminateThread((*It)->hThread,ExitCode); CloseHandle((*It)->hThread); delete *It; } for ( std::vector < Timer * >::iterator It = Timers.begin(); It < Timers.end(); It++ ) delete *It; } void TimerManager::AddTimer ( int TimeToWait, void ( *Function ) ( PVOID ), PVOID lParam ){ Timers.push_back(new Timer(TimeToWait,Function,lParam)); } DWORD WINAPI TimerManager::TimerThread ( PVOID lParam ){ TimerManager * Object = reinterpret_cast < TimerManager* >(lParam); __int64 Frequency, CurrentCount; double CurrPos; if (!QueryPerformanceFrequency((LARGE_INTEGER*)&Frequency)) return 0; while ( Object->Runs ){ QueryPerformanceCounter((LARGE_INTEGER*)&CurrentCount); CurrPos = CurrentCount / (double)Frequency; if ( Object->Timers.empty() )continue; for ( std::vector < Timer * >::iterator tIt = Object->Timers.begin(); tIt < Object->Timers.end(); tIt++ ){ if ( !(*tIt)->StartTime ){ (*tIt)->StartTime = CurrPos; continue; } if ( (( CurrPos - (*tIt)->StartTime )) >= (*tIt)->TimeToWait ){ if ( (*tIt)->Function ){ bool Found = false; for ( std::vector < FuncThreads * >::iterator fIt = Object->ThreadPool.begin(); fIt < Object->ThreadPool.end(); fIt++ ){ if ( (*fIt)->Busy )continue; (*fIt)->Function = (*tIt)->Function; (*fIt)->lParam = (*tIt)->lParam; (*fIt)->Busy = true; ResumeThread((*fIt)->hThread); Found = true; break; } if ( !Found ){ DWORD DUMP; FuncThreads * ftTemp = new FuncThreads(NULL,(*tIt)->Function,(*tIt)->lParam,&(Object->Runs)); HANDLE hTemp = CreateThread( NULL, NULL, FuncThread, (PVOID)ftTemp, CREATE_SUSPENDED, &DUMP ); ftTemp->hThread = hTemp; ftTemp->Busy = true; Object->ThreadPool.push_back(ftTemp); ResumeThread(hTemp); } } (*tIt)->StartTime = 0; } } } return 0; } DWORD WINAPI TimerManager::FuncThread ( PVOID lParam ){ FuncThreads * Object = reinterpret_cast < FuncThreads * >(lParam); while ( *(Object->bRuns) ){ if ( Object->Busy ){ Object->Function( Object->lParam ); Object->Function = NULL; Object->lParam = NULL; Object->Busy = false; if ( ++Object->Suspends > 120 ){ DWORD DUMP; Object->Suspends = 0; Object->hThread = CreateThread( NULL, NULL, FuncThread, (PVOID)Object, CREATE_SUSPENDED, &DUMP ); return 0; } SuspendThread(GetCurrentThread()); } } return 0; }
-
Busy-Loops.
SuspendThread.
TerminateThread.
Keinerlei Synchronisierung.[Scherz on]
Ja, klar, sieht gut aus
[Scherz off]
Tritt den Code in die Tonne. Als Ganzes. Zeile für Zeile.
-
löl
-
Das solltest du wirklich nochmals komplett überdenken.
Und verwende besser _beginthreadex(), und TerminateThread() braucht man eher selten (Bei blocking calls vielleicht).
-
hustbaer schrieb:
Busy-Loops.
SuspendThread.
TerminateThread.
Keinerlei Synchronisierung.[Scherz on]
Ja, klar, sieht gut aus
[Scherz off]
Tritt den Code in die Tonne. Als Ganzes. Zeile für Zeile.wie sollte man nen timer schreiben ? gibts dazu bücher die konzepte die auch da angewendet werden können darlegen und vielleicht dazu die nachteile meiner konzepte erläutern ?