CreateThread()-does it leak the OS thread handle?

Just starting out? Need help? Post your questions and find answers here.
User avatar
Mijikai
Addict
Addict
Posts: 1360
Joined: Sun Sep 11, 2016 2:17 pm

CreateThread()-does it leak the OS thread handle?

Post by Mijikai »

Before opening a bug report i want to ask here. :|

My OS is Windows and MSDN says this about threads:
The thread object remains in the system until the thread has terminated
and all handles to it have been closed through a call to CloseHandle.
When a thread in PB is created i can get the OS thread handle with ThreadID().
Which means the OS thread handle is open!

Now the problem is - there is no information on how and if the OS thread handle is closed?
In other words is it leaked?
Last edited by Mijikai on Wed Jan 06, 2021 7:29 pm, edited 2 times in total.
infratec
Always Here
Always Here
Posts: 6883
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: CreateThread() - does it leak the OS thread handle?

Post by infratec »

Code: Select all

IsThread()
This checks if the thread is running or not.

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()
User avatar
Mijikai
Addict
Addict
Posts: 1360
Joined: Sun Sep 11, 2016 2:17 pm

Re: CreateThread() - does it leak the OS thread handle?

Post by Mijikai »

infratec wrote:

Code: Select all

IsThread()
This checks if the thread is running or not.

Normally you terminate a running thread before you leave the program.
(If it is still running)
...
Im not asking about terminating a thread!
Im concerned about the OS thread handle.
User avatar
Paul
PureBasic Expert
PureBasic Expert
Posts: 1252
Joined: Fri Apr 25, 2003 4:34 pm
Location: Canada
Contact:

Re: CreateThread() - does it leak the OS thread handle?

Post by Paul »

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.
Image Image
infratec
Always Here
Always Here
Posts: 6883
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: CreateThread() - does it leak the OS thread handle?

Post by infratec »

:?: :?: :?:

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.
User avatar
Mijikai
Addict
Addict
Posts: 1360
Joined: Sun Sep 11, 2016 2:17 pm

Re: CreateThread() - does it leak the OS thread handle?

Post by Mijikai »

I want to know how/when and if PB closes the OS thread handle.

So far the only explanation that makes sense is that those handles get closed when
the program terminates.

Even so that is still an issue if your application keeps on creating threads.

Once again the OS thread handle needs to be closed seperately once the thread has terminated!
User avatar
NicTheQuick
Addict
Addict
Posts: 1227
Joined: Sun Jun 22, 2003 7:43 pm
Location: Germany, Saarbrücken
Contact:

Re: CreateThread() - does it leak the OS thread handle?

Post by NicTheQuick »

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.
User avatar
Mijikai
Addict
Addict
Posts: 1360
Joined: Sun Sep 11, 2016 2:17 pm

Re: CreateThread() - does it leak the OS thread handle?

Post by Mijikai »

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.

Edit: Well, I just posted as you did it too.

Exactly, thats what i want to know :)
User avatar
NicTheQuick
Addict
Addict
Posts: 1227
Joined: Sun Jun 22, 2003 7:43 pm
Location: Germany, Saarbrücken
Contact:

Re: CreateThread() - does it leak the OS thread handle?

Post by NicTheQuick »

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.
User avatar
Mijikai
Addict
Addict
Posts: 1360
Joined: Sun Sep 11, 2016 2:17 pm

Re: CreateThread() - does it leak the OS thread handle?

Post by Mijikai »

That sounds plausible but should be fixed aswell.
I will open a Bug-Report by the end of the week.
User avatar
Mijikai
Addict
Addict
Posts: 1360
Joined: Sun Sep 11, 2016 2:17 pm

Re: CreateThread() - does it leak the OS thread handle?

Post by Mijikai »

I made some Tests :)

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!

So we have a problem that should be fixed!

Here is my test code for those interested:

Code: Select all

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
freak
PureBasic Team
PureBasic Team
Posts: 5929
Joined: Fri Apr 25, 2003 5:21 pm
Location: Germany

Re: CreateThread() - does it leak the OS thread handle?

Post by freak »

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.
quidquid Latine dictum sit altum videtur
User avatar
Mijikai
Addict
Addict
Posts: 1360
Joined: Sun Sep 11, 2016 2:17 pm

Re: CreateThread() - does it leak the OS thread handle?

Post by Mijikai »

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.
Thank you for explaining :)
User avatar
NicTheQuick
Addict
Addict
Posts: 1227
Joined: Sun Jun 22, 2003 7:43 pm
Location: Germany, Saarbrücken
Contact:

Re: CreateThread()-does it leak the OS thread handle?

Post by NicTheQuick »

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.
freak
PureBasic Team
PureBasic Team
Posts: 5929
Joined: Fri Apr 25, 2003 5:21 pm
Location: Germany

Re: CreateThread()-does it leak the OS thread handle?

Post by freak »

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.
quidquid Latine dictum sit altum videtur
Post Reply