Normally you terminate a running thread before you leave the program.
(If it is still running)
I always use PostEvent() to send an event to the main program when the thread is started and when it is finished.
So I know the state of a thread, without checking always via IsThread()
Mijikai wrote:
Im not asking about terminating a thread!
Im concerned about the OS thread handle.
What exactly are you asking?
If you are wanting to know what happens to the thread when finished, PB takes care of it according to the Help file...
A thread runs within your program, it's not another process. When the main program exits, all the threads are destroyed. Under PureBasic, threads are simply a procedure which is called asynchronously. The thread runs until the procedure exits.
Last edited by Paul on Tue Jan 05, 2021 8:57 pm, edited 1 time in total.
The PB thread is an OS thread.
If the PB thread is running, the OS thread is still running, since it is the same.
You can not kill the OS thread without killing the PB thread, since it is the same.
Use SysInternals ProcessExplorer to have a look on it.
So you want to know if Purebasic automatically recognizes if a thread has ended and then calls CloseHandle accordingly? Or if Purebasic only calls CloseHandle if the whole program ends?
If it is the latter you may have a memory leak, that's correct. But unfortunately I don't know.
Edit: Well, I just posted as you did it too.
The english grammar is freeware, you can use it freely - But it's not Open Source, i.e. you can not change it or publish it in altered way.
NicTheQuick wrote:So you want to know if Purebasic automatically recognizes if a thread has ended and then calls CloseHandle accordingly? Or if Purebasic only calls CloseHandle if the whole program ends?
If it is the latter you may have a memory leak, that's correct. But unfortunately I don't know.
My guess is that it does not call CloseHandle automatically but uses that handle until the whole program terminates because otherwise IsThread could not work properly.
The english grammar is freeware, you can use it freely - But it's not Open Source, i.e. you can not change it or publish it in altered way.
Conclusion:
- If a thread ends the OS thread handle will NOT be closed!
- The OS thread handle is only closed if the application terminates or KillThread() is called!
EnableExplicit
Procedure.i Thread(Parameter.i)
PrintN("Thread Parameter: " + Str(Parameter))
Delay(1000);<- just so we have enough time!
ProcedureReturn
EndProcedure
Procedure.i Main()
Protected id.i
Protected hthread.i
Protected hinfo.i
If OpenConsole(#Null$)
PrintN("")
PrintN("Start Test 1!")
PrintN("Running Thread!")
id = CreateThread(@Thread(),123)
hthread = ThreadID(id)
PrintN("Thread is Valid: " + Str(IsThread(id)))
PrintN("Thread Handle is Open: " + Str(GetHandleInformation_(hthread,@hinfo)))
WaitThread(id)
PrintN("Thread has closed!")
PrintN("Thread is Valid: " + Str(IsThread(id)))
PrintN("Thread Handle is Open: " + Str(GetHandleInformation_(hthread,@hinfo)))
PrintN("Calling CloseHandle_()!")
CloseHandle_(hthread)
PrintN("Thread Handle is Open: " + Str(GetHandleInformation_(hthread,@hinfo)))
PrintN("")
PrintN("Start Test 2!")
PrintN("Running Thread!")
id = CreateThread(@Thread(),123)
hthread = ThreadID(id)
PrintN("Thread is Valid: " + Str(IsThread(id)))
PrintN("Thread Handle is Open: " + Str(GetHandleInformation_(hthread,@hinfo)))
KillThread(id)
PrintN("Thread is Valid: " + Str(IsThread(id)))
PrintN("Thread Handle is Open: " + Str(GetHandleInformation_(hthread,@hinfo)))
Input()
CloseConsole()
EndIf
ProcedureReturn
EndProcedure
Procedure.i Thread3(Parameter.i)
Repeat
Delay(1000)
ForEver
ProcedureReturn
EndProcedure
Procedure.i Test3()
Protected id.i
Protected hthread.i
Protected hinfo.i
If OpenConsole(#Null$)
PrintN("")
PrintN("Start Test 1!")
PrintN("Running Thread!")
id = CreateThread(@Thread(),123)
hthread = ThreadID(id)
PrintN("Thread is Valid: " + Str(IsThread(id)))
PrintN("Thread Handle is Open: " + Str(GetHandleInformation_(hthread,@hinfo)))
PrintN("Handle: " + Str(hthread))
PrintN("Handle is now in the Clipboard!")
SetClipboardText(Str(hthread))
PrintN("Closing Program without ending the thread!")
Delay(3000)
CloseConsole()
EndIf
EndProcedure
Procedure.i Check(Handle.i)
Protected hinfo.i
ProcedureReturn GetHandleInformation_(Handle,@hinfo)
EndProcedure
Main();<- un comment this and then run Test3()!
;Test3();<- un comment this and run Check() to see if the handle is leaked!
;Debug Check(268);<- paste the handle!
End
Handles of ended threads are closed (and purged from internal data structures) when a new thread is created. This prevents resources from increasing past the number of threads that run concurrently. So it is not really a leak that keeps growing. You are right though: If you just create one thread then this handle will stay open until the end. However, this is not problematic.
freak wrote:Handles of ended threads are closed (and purged from internal data structures) when a new thread is created. This prevents resources from increasing past the number of threads that run concurrently. So it is not really a leak that keeps growing. You are right though: If you just create one thread then this handle will stay open until the end. However, this is not problematic.
Just one more question to a similar thing:
What exactly happens when the main program terminates while one or more threads are still running? Will they be killed or what happens in the background?
The english grammar is freeware, you can use it freely - But it's not Open Source, i.e. you can not change it or publish it in altered way.
NicTheQuick wrote:Just one more question to a similar thing:
What exactly happens when the main program terminates while one or more threads are still running? Will they be killed or what happens in the background?
We leave them running but the OS will kill/clean them up as part of the process shutdown. If we tried to do the cleanup ourselves (before shutdown), there is a great danger for deadlocks. The OS cleanup can prevent deadlock by forcefully terminating the process if there is danger of a deadlock during shutdown.