Thread "booten"
-
Hallo!
Ich bin totaler Neuling was Threads in der Win API angeht; das Konzept ist mir jedoch bekannt. Ich möchte wissen wie ich einen Thread dazu bringen kann wieder an den Anfang der Process-Funktion zu springen.
Ich gebe einmal folgendes Beispiel:
DWORD WINAPI ThreadProc (PVOID pParam) { while(TRUE) { SleepEx(100, FALSE); keybd_event(VK_SPACE, 0x39, 0x00, 0); //SPACE DOWN SleepEx(20, FALSE); keybd_event(VK_SPACE, 0x39, KEYEVENTF_KEYUP, 0); //SPACE UP } return 0; }
Der Thread wird am Anfang so erstellt, dass er im suspendiertem Zustand ist.
An einer bestimmten Stelle im Programm wecke ich den Thread, damit er beginnt den Code ständig auszuführen. An einer anderen Stelle suspendiere ich ihn wieder. D.h. diese Anweisungen sind an zwei Ereignisse verknüpft die jedoch immer nur aufeinanderfolgend auftreten können. Meine konkrete Frage zu dem Beispiel ist jetzt: Es kann ja passieren, dass der Thread gerade dann suspendiert wird wenn er gerade dabei ist einer der keybd_event Funktionen auszuführen. Ich möchte nun erreichen, dass die Process-Funktion beim nächsten Erwachen des Threads seine Arbeit nicht wieder an dem Punkt aufnimmt wo er unterbrochen wurde, sondern ...schon wissen.Ich danke bereits im V.orraus für jegliche Hilfe.
PS.: Die Suchfunktion konnte mir nicht weiter helfen, da der Begriff 'Thread' eine allgemeine Bedeutung hat und deshalb sehr oft vorkommt.
Kann mir einer sagen warum das Wort "V.orraus" zensiert wird?
-
Dein Thread endet nie. Das ist nicht gut.
Nimm doch z.B. ein Event mit manual reset. Der Thread ruft einfach am Ende jedes Schleifendurchlaufes WaitForSingleObject auf.
Solange das Event signalisiert ist, läuft der Thread weiter.
Sobald ein anderer Thread das Event "unsignalisiert", also zurücksetzt, stoppt der Thread in einem definierten Zustand, nämlich bei dem WaitForSingeObject-Aufruf.
Von dort kannst du ihn dann weiterlaufen lassen, indem du das Event wieder signalisierst.Du wirst u.U. ein weiteres Event, eine globale Variable oder den Parameter pVoid brauchen. Wie willst du den Thread denn sonst beenden?
Ein Thread muss immer auslaufen. TerminateThread aufzurufen ist verboten, und ExitThread ist auch nicht das Gelbe vom Ei.
-
Aziz schrieb:
Kann mir einer sagen warum das Wort "V.orraus" zensiert wird?
Du hast es falsch geschrieben! Es heißt Voraus - also mit einem r
-
@cd9000
Danke für den Hinweis mit den Events. Das muss ich mir näher ansehen..
Ich wusste nicht, dass hier Rechtschreibfehler so streng gehandhabt werden.
-
Ich wär für ne globale Variable. Is einfacher.
-
Ich hab jetzt die Vorschläge von cd9000 umgesetzt, und mein Sourcecode sieht folgendermaßen aus:
HINSTANCE g_hDllInstance; //Variablen und Funktionen die in Zusammenhang mit dem Thread stehen DWORD WINAPI ThreadProc (PVOID pParam); HANDLE g_hThread = 0; // Handle zum Thread HANDLE g_hEvent = 0; // Handle zum Event DWORD g_idThread = NULL; // Thread-ID BOOL g_bRunning = 1; // Thread rennt solange diese Variable TRUE ist BOOL APIENTRY DllMain(HINSTANCE hInstance, DWORD fdwReason, PVOID pvReserved) { // Perform actions based on the reason for calling. switch(fdwReason) { case DLL_PROCESS_ATTACH: // Initialize once for each new process. // Return FALSE to fail DLL load g_hDllInstance = hInstance; g_hThread = CreateThread( NULL, NULL, ThreadProc, NULL /*pParam*/, NULL /*CREATE_SUSPENDED*/, &g_idThread); if(!g_hThread) return FALSE; // Thread konnte nicht erstellt werden break; case DLL_THREAD_ATTACH: //SetThreadPriority(g_hThread, THREAD_PRIORITY_NORMAL); // Priorität des Threads einstellen g_hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); // Ein Event für Thread-Proc erstellen break; case DLL_THREAD_DETACH: break; case DLL_PROCESS_DETACH: g_bRunning = FALSE; CloseHandle(g_hThread); CloseHandle(g_hEvent); break; } return TRUE; // Successful DLL_PROCESS_ATTACH. } DWORD WINAPI ThreadProc (PVOID pParam) { while(g_bRunning) // { WaitForSingleObject(g_hEvent, INFINITE); //if the event is signaled, the function returns immediately keybd_event(VK_SPACE, 0x39, 0x00, 0); //SPACE DOWN SleepEx(1, FALSE); keybd_event(VK_SPACE, 0x39, KEYEVENTF_KEYUP, 0); //SPACE UP SleepEx(1, FALSE); } return 0; }
Wie ihr wahrscheinlich erkennen könnt, existiert dieser Thread in einer DLL. Sobald diese DLL geladen wird, wird auch der Thread erstellt, und im Nachhinein ein Event dafür. Das Problem, das ich jetzt habe ist, dass die Variable g_bRunning solange TRUE sein muss, solange die DLL geladen ist. Was meint ihr? Sind die drei Zeilen unter DLL_PROCESS_DETACH in Ordnung? (Die DLL brauche ich damit ich meinen Keyboard Hook systemweit wirken lassen kann).