Archived

This topic is now archived and is closed to further replies.

ANSI2000

Closing a thread handle (WIN 32).

Recommended Posts

The MSDN documents state that for a thread to be completly gone, both the handle must be closed and the thread exit gracefully... Is it dangerous to close the handle of the thread as it is executing? The thread still works if you close the handle. Personally for my application needs I do not need the handle to call other thread functions to check state etc...

Share this post


Link to post
Share on other sites
Yes you do. You may not need functions like suspend and resume, but if you want to make sure the thread terminates as the application closes you'll need 'WaitForSingleObject' (assuming Win32) and if the thread doesn't terminate within a certain timelimit 'TerminateThread'.

Otherwise it may happen that your application is closed, but the thread is still running. It may not be a dangerous thing, but it's a waste of system resources.

edit: Also, if the thread crashes for some reason, terminating it may be the only way to get rid of it. If you have already closed the handle you can't do that anymore.

[edited by - Wildfire on November 17, 2003 11:55:00 AM]

Share this post


Link to post
Share on other sites
You can close the thread handle. You can always get the thread handle back by calling OpenThread when you need it. You do not need to exit the thread before closing your program as the thread will die with the program, and no resource leak will occur.

[How To Ask Questions|STL Programmer''s Guide|Bjarne FAQ|C++ FAQ Lite|C++ Reference|MSDN]

Share this post


Link to post
Share on other sites

HANDLE OpenThread
(
DWORD dwDesiredAccess,
BOOL bInheritHandle,
DWORD dwThreadId
);


He'll still have to know the thread id to do that. Also, as far as I've read it's only supported on WinXP,2k Pro,WinME and 2003.

I don't see much difference in having to store either an id, or a handle. But the handle would allow for more direct access.

quote:

You do not need to exit the thread before closing your program as the thread will die with the program, and no resource leak will occur.


Like I said, the thread may crash, and you may want to terminate it.

Also, I've had the case were I 'closed' an application (=the window was gone) but one of the threads was still running. It was stuck in an endless loop and never came to the point where '_endthread' would've stopped it.
Until I added the 'WaitForSingleObject' (and a messagebox on timeout) I never even noticed my programm was still running in the background.

[edited by - Wildfire on November 17, 2003 12:48:54 PM]

Share this post


Link to post
Share on other sites
A thread executes until one of the following events occurs:

- The thread calls the ExitThread function.
- Any thread of the process calls the ExitProcess function.
- The thread function returns.
- Any thread calls the TerminateThread function with a handle to the thread.
- Any thread calls the TerminateProcess function with a handle to the process.

Warning: The TerminateThread and TerminateProcess functions should be used only in extreme circumstances, since they do not allow threads to clean up, do not notify attached DLLs, and do not free the initial stack.

[How To Ask Questions|STL Programmer''s Guide|Bjarne FAQ|C++ FAQ Lite|C++ Reference|MSDN]

Share this post


Link to post
Share on other sites
You should ''join'' the thread prior to terminating your application - this is done under Win32 using WaitForSingleObject (or WaitForMultipleObjects) on the thread handle.

It is not an error under Win32 to join a terminated thread, the wait call will return immediately. This is why you need to close the thread handle; until all handles to it are closed, OS resources for the thread are still consumed.

Share this post


Link to post
Share on other sites
My application will never end it''s a "high" end server application running as a service for Win2K.

The program was written using blocking sockets... Now I canot change the architecture but to only patch it! The major problem with the ap is that it would run out of resources because to many handles where beeing created and not closed which would cause Winsock to return WSANOBUFFS error. I fixed the problem by closing the handle right away, which lead me to ask this question...

Bassically...

Loop;
accept();

HANDLE aHandle;
aHandle = CreateThread();

if(aHandle == NULL)
//Check error
Else
CloseHandle();

Share this post


Link to post
Share on other sites
Do you have to call CloseHandle on the handle (_beginthreadex() I''m talking about here) when its done executing? That is to say, which option would work?

a. close it right after you open it and rely on the thread ending to drop the reference count to zero to clean up the resources (seems like they would do this for you?)

b. marshal the handle into a stub function that executes the thread and then closes it after it returns (e.g. hijack the thread start function, stick the user''s thread start in there, a HANDLE of the thread executing (thats if its okay for a thread to call CloseHandle on it''s own handle?) and the arguments of the thread procedure.

c. make the user keep the handle open for as long as its executing.

I use option C right now but if B is possible it would be great to prevent resource leaks.

Share this post


Link to post
Share on other sites
quote:
Original post by dalleboy
A thread executes until one of the following events occurs:

- The thread calls the ExitThread function.
- Any thread of the process calls the ExitProcess function.
- The thread function returns.
- Any thread calls the TerminateThread function with a handle to the thread.
- Any thread calls the TerminateProcess function with a handle to the process.

Warning: The TerminateThread and TerminateProcess functions should be used only in extreme circumstances, since they do not allow threads to clean up, do not notify attached DLLs, and do not free the initial stack.



TerminateProcess is always safe. When the process terminates, all the resources are freed (including its address space, threads and kernel structures)


Share this post


Link to post
Share on other sites
quote:
Original post by ANSI2000

Is it dangerous to close the handle of the thread as it is executing? The thread still works if you close the handle. Personally for my application needs I do not need the handle to call other thread functions to check state etc...


oh, and since threads are ref counted, and kernel keep a separate count for it until exits, you can call CloseHandle when you want. I actually call it just after CreateThread very often.

Share this post


Link to post
Share on other sites
Well one method that could work really well is to create a thread that will check the status of all other threads using WaitForObject... and close handles as needed. This status thread will only exit at the shutdown process of the application and it''s handle can be closed then...

I was thinking of writting a small Thread Manager class using sort of a command pattern. Where each thread can be passed an "object" and the thread can then call something like object->execute();... And the thread manager can then handle all the cleanup etc.. of the threads...

Share this post


Link to post
Share on other sites
quote:
Original post by Lorenzo
TerminateProcess is always safe. When the process terminates, all the resources are freed (including its address space, threads and kernel structures)


Not according to Microsoft themselves.

[How To Ask Questions|STL Programmer''s Guide|Bjarne FAQ|C++ FAQ Lite|C++ Reference|MSDN]

Share this post


Link to post
Share on other sites
The warnings about TerminateProcess is just Microsoft covering it''s ass because developers do dumb things. If the app has cached data that data may be lost. If the app requires some sort of network handshake or the nuclear reactor explodes that handshake isn''t going to happen. etc, etc. Basically the deal is that your app will get cleaned up but another other processes that rely on your app shutting down gracefully are out of luck. Developers are supposed to handle ungraceful shutdowns but often don''t.

The warnings about TerminateThread on the other hand are real. Don''t ever use it for any reason. It''s better to shutdown your app and make the user restart it rather than gambling on TerminateThread working and leaving your app in a clean state.


Share this post


Link to post
Share on other sites
quote:
TerminateProcess is always safe.

No it isn''t.

quote:
When the process terminates, all the resources are freed (including its address space, threads and kernel structures)

And if the program is manipulating some cross-process shared state at the time it''s terminated?

The kernels not going to unfuck the data for you.

TerminateProcess() is not safe.

Share this post


Link to post
Share on other sites
quote:
The warnings about TerminateProcess is just Microsoft covering it''s ass because developers do dumb things.

No, they''re MS making the dangers of the TerminateProcess() function absolutely clear.

An app can''t handle TerminateProcess() gracefully -- it doesn''t get the chance -- so as a result it can, for instance, leave files partially written and corrupt shared state. There''s nothing you can do about this, so the only answer is don''t call TerminateProcess(). It''s dangerous for all the same reasons that TerminateThread() is dangerous.

Share this post


Link to post
Share on other sites