Page 1 of 1
Thread state
Posted: Wed Jun 05, 2013 3:22 am
by Blankname
I'm trying to check if a thread is suspended or not, and can't seem to get the code I wrote to work.
Code: Select all
Procedure MainThread(parameter)
Repeat
Delay(1000)
PrintN("Thread Message")
ForEver
EndProcedure
OpenConsole()
Thread = CreateThread(@MainThread(), 1)
Timer = ElapsedMilliseconds()
Repeat
Delay(1000)
If WaitForSingleObject_(ThreadID(Thread), 0) = #WAIT_ABANDONED
PrintN("Thread Suspended")
EndIf
Timed = ElapsedMilliseconds()-Timer
If Timed > 5000
PauseThread(Thread)
EndIf
ForEver
Re: Thread state
Posted: Wed Jun 05, 2013 6:20 am
by Demivec
Blankname wrote:I'm trying to check if a thread is suspended or not, and can't seem to get the code I wrote to work.
#WAIT_ABANDONED is for a mutex object.
Re: Thread state
Posted: Wed Jun 05, 2013 6:43 am
by RASHAD
Not very accurate because you are using many delays
And you are not suppose to use consecutive PauseThread()
Code: Select all
Procedure MainThread(parameter)
Repeat
Delay(1000)
PrintN("Thread Message")
ForEver
EndProcedure
OpenConsole()
Thread = CreateThread(@MainThread(), 1)
Timer = ElapsedMilliseconds()
Repeat
Delay(1000)
If WaitForSingleObject_(ThreadID(Thread), 10000) = #WAIT_TIMEOUT
PrintN("Thread Suspended")
EndIf
Timed = ElapsedMilliseconds()-Timer
If Timed > 5000 And pause = 0
PauseThread(Thread)
pause = 1
EndIf
ForEver
Re: Thread state
Posted: Wed Jun 05, 2013 7:46 am
by Blankname
RASHAD wrote:Not very accurate because you are using many delays
And you are not suppose to use consecutive PauseThread()
Code: Select all
Procedure MainThread(parameter)
Repeat
Delay(1000)
PrintN("Thread Message")
ForEver
EndProcedure
OpenConsole()
Thread = CreateThread(@MainThread(), 1)
Timer = ElapsedMilliseconds()
Repeat
Delay(1000)
If WaitForSingleObject_(ThreadID(Thread), 10000) = #WAIT_TIMEOUT
PrintN("Thread Suspended")
EndIf
; Timed = ElapsedMilliseconds()-Timer
; If Timed > 5000 And pause = 0
; PauseThread(Thread)
; pause = 1
EndIf
ForEver
It ends up spurting "Thread Suspended" every 10 seconds when the timeout expires if you comment out the pausing. GetLastError_() returns 6 "Invalid Handle".
Re: Thread state
Posted: Wed Jun 05, 2013 10:18 am
by Demivec
Wouldn't it be easier to just record whether the thread is paused in a variable (or array, list, etc.) and then check that for its status?
Re: Thread state
Posted: Wed Jun 05, 2013 10:59 am
by RASHAD
As Demivec stated you can use some other way to get it like Flag
Unfortunately WaitForSingleObject_() respond only for #WAIT_TIMEOUT event
That is how Fred designed CreateThread()
I guess you want a message when the Thread is paused or resumed instantly
Re: Thread state
Posted: Wed Jun 05, 2013 7:23 pm
by Blankname
RASHAD wrote:As Demivec stated you can use some other way to get it like Flag
Unfortunately WaitForSingleObject_() respond only for #WAIT_TIMEOUT event
That is how Fred designed CreateThread()
I guess you want a message when the Thread is paused or resumed instantly
I'm spawning a couple of "checker threads" that's sole purpose is to make sure the main thread hasn't ended or been suspended.
Re: Thread state
Posted: Wed Jun 05, 2013 8:15 pm
by RichAlgeni
I use event handles to accomplish what you want. First create the events, I store them in dimensioned arrays:
Code: Select all
For threadNumber=0 To numberThreads
thisEvent(threadNumber) = CreateEvent_(0, 0, 0, #ProgramName + "_Event_" + Str(threadNumber))
Next
Then I create threads for each event:
Code: Select all
For threadNumber=0 To numberThreads
CreateThread(@ProcessRQST(), threadNumber)
Next
Here are the procedures, waiting forever:
Code: Select all
Procedure.i ProcessRQST(requestNumber.i)
Repeat
WaitForSingleObject_(thisEvent(requestNumber), #INFINITE)
...
The I can call the Windows API function to trigger the event:
To end the process, I just set a global variable
ShutDownNow to #True, then fire all of the events. If
ShutDownNow is #True, the threaded procedures end.
Re: Thread state
Posted: Wed Jun 05, 2013 10:21 pm
by jassing
Blankname wrote:I'm spawning a couple of "checker threads" that's sole purpose is to make sure the main thread hasn't ended or been suspended.
Is "the main thread" the executable program being run, and it creates the "checker threads"?
If so, if the exe (and thus, 'the main thread') ends/exits/errors out/crashes, the "checker threads" will die with it.
Re: Thread state
Posted: Mon Jun 10, 2013 10:41 am
by Blankname
jassing wrote:Blankname wrote:I'm spawning a couple of "checker threads" that's sole purpose is to make sure the main thread hasn't ended or been suspended.
Is "the main thread" the executable program being run, and it creates the "checker threads"?
If so, if the exe (and thus, 'the main thread') ends/exits/errors out/crashes, the "checker threads" will die with it.
I'm spawning three new threads on AttachProcess(), one is the main executed code and the other two are the checker threads to make sure the first thread is running.
Re: Thread state
Posted: Tue Jun 11, 2013 8:25 am
by Blankname
RichAlgeni wrote:I use event handles to accomplish what you want. First create the events, I store them in dimensioned arrays:
Code: Select all
For threadNumber=0 To numberThreads
thisEvent(threadNumber) = CreateEvent_(0, 0, 0, #ProgramName + "_Event_" + Str(threadNumber))
Next
Then I create threads for each event:
Code: Select all
For threadNumber=0 To numberThreads
CreateThread(@ProcessRQST(), threadNumber)
Next
Here are the procedures, waiting forever:
Code: Select all
Procedure.i ProcessRQST(requestNumber.i)
Repeat
WaitForSingleObject_(thisEvent(requestNumber), #INFINITE)
...
The I can call the Windows API function to trigger the event:
To end the process, I just set a global variable
ShutDownNow to #True, then fire all of the events. If
ShutDownNow is #True, the threaded procedures end.
WaitForSingleObject waits until a thread is finished tho doesn't it? To clarify what I am doing I will post a example code below. The purpose is for a simple anti-cheat engine for my game, and the purpose for the checker threads it keep players from just simply suspending the main thread (with all the important checks) and bypassing it completely. With a few checker threads constantly monitoring the main thread, it will make it much harder to bypass with software like Process Explorer. Tho it would be better if every thread checked each other.
Code: Select all
Procedure MainThread(Value.i)
Repeat
; All The Main Code
ForEver
EndProcedure
Procedure CheckerThread(Value.i)
Repeat
; Checks If Main Thread Is Still Active + Running (Not Suspended)
; Checks If Checker Thread 1 + 2 Is Still Active + Running (Not Suspended)
ForEver
EndProcedure
ProcedureDLL AttachProcess(Instance)
Thread1 = CreateThread(@MainThread(), 1)
Thread2 = CreateThread(@CheckerThread(), 2)
Thread3 = CreateThread(@CheckerThread(), 3)
EndProcedure
Re: Thread state
Posted: Tue Jun 11, 2013 4:22 pm
by RichAlgeni
WaitForSingleObject_(thisEvent(requestNumber), #INFINITE) can be used anywhere, not just in a thread. It waits the amount of time specified in the second parameter. In the above case, it will wait forever, but just until
SetEvent_(thisEvent(requestNumber)) is executed, in which case it will go on it's way. You can also use a timer in the second parameter:
http://msdn.microsoft.com/en-us/library ... s.85).aspx
Once the timer expires, execution will continue in the same way as if an event fired. You don't need to use SetEvent, unless you want the execution to continue for any reason before a time expires.
You can use this in your checker threads to periodically wake up and check the main thread.
Re: Thread state
Posted: Wed Jun 12, 2013 5:22 am
by Blankname
This works for me, ResumeThread doesn't return true until the specified thread is paused (suspended). So I don't have to suspend the thread at all, this is a much more efficient way to check if a thread is suspended (plus it just resumes it if it was).
Code: Select all
Global Thread1, Thread2
Procedure MainThread(Value.i)
Repeat
PrintN("Thread Message [" + Str(Random(99, 10)) + "]")
Delay(1000)
ForEver
EndProcedure
Procedure CheckerThread(Value.i)
Repeat
If IsThread(Thread1)
If ResumeThread(Thread1)
PrintN("Thread Suspended!")
EndIf
Else
PrintN("Thread Killed!")
EndIf
Delay(1000)
ForEver
EndProcedure
OpenConsole()
Thread1 = CreateThread(@MainThread(), 1)
Thread2 = CreateThread(@CheckerThread(), 2)
Repeat
Delay(1)
ForEver
Re: Thread state
Posted: Wed Jun 12, 2013 5:26 pm
by RichAlgeni
Very good!