in some recent discussions here and in other groups we had
the question whether it is allowed to use the c[++] runtime
in threads not created through _beginthreadex() but through
CreateThread() --> e.g. worker threads from w2k thead pools
(-> BindIoCompletionCallback()) or from RPC/COM-MTA thread
pools - the problem would be especially some memory leak
when such worker threads exit, and thats normal for them.
The docu in different chapters seems to say "must start
thread with _beginthread", otherwise parts of the CRT would
not work and resources would be lost at thread exit.
Also a posting from Jon Wiswall <jon...@microsoft.com> seems
to imply this (Subject: Re: thread pool and CRT; Date: Thu,
28 Feb 2002 09:51:05 -0800, Message-ID: <O7LtoBIwBHA.2540@tkmsftngp04>
Newsgroups: microsoft.public.win32.programmer.kernel).
This would be great problems when either using w2k thread
pools or implementing a free threaded COM server.
But on the other hand there are some good reasons and
experience that the CRT will work on any thread, and under
normal circumstances the CRT DLL will do any necessary
thread data cleanup during its entry point called with
DLL_THREAD_DETATCH.
So I and some others would be really happy when some
expert from the MS CRT team could remove our confusion !
Thanks,
Markus.
If you are using the dll version of CRT (msvc*.dll), there won't be any
leak.
See the implementation of _DllMainCRTStartup in CRT\src\ crtdll.c.
If you are using the static version of crt (libc or libcmt) there will be
leak.
Thank you,
Bobby Mattappally
Microsoft Developer Support
This posting is provided "AS IS" with no warranties, and confers no rights.
Thanks, this removes my doubts !
Would it be an option to make the docu more clear about this issue,
e.g. for CreateThread() and ExitThread() it currently contains ..
A thread that uses functions from the C run-time libraries should use
the beginthread and endthread C run-time functions for thread management
rather than CreateThread and ExitThread. Failure to do so results in small
memory leaks when ExitThread is called.
I will send your feedback to the docs team.
Regards,
Vladimir.
Thanks,
Markus.
On one hand you say:
"A thread that uses functions from the static C run-time libraries should
use
the beginthread or beginthreadex and endthread or endthreadex C run-time
functions for thread management rather than CreateThread and ExitThread.
Failure to do so results in small
memory leaks when ExitThread is called"
On the other hand you say:
I"f you are using the dll version of CRT (msvc*.dll), there won't be any
leak.
See the implementation of _DllMainCRTStartup in CRT\src\ crtdll.c.
If you are using the static version of crt (libc or libcmt) there will be
leak."
What happens if I use beginthread and crt (libc or libcmt) ?
Will there be no memory leak because I use beginthread instead of
CreateThread although I don't compile with
msvcrt or msvcrtd?
Thank you in advance for you response
Serge
But when you look at the doku for [win32::]raise(), crashing
the application is just the documented behaviour for all supported
signals except SIGTERM, and even for SIGTERM I wouldnt call
it unexpected or undesired ?-)
So what remains is when some code wants to install its own
signal handler by using signal(mySignalHandler). But please
note that the docu (or CRT source ?) shows that for most signals
there are no thread specific handlers.
My point is: concerning my code's CRT usage on misc threads I dont
want to introduce resource leaks or undefined behaviour.
But IMHO (under win32 !) any code using signals on misc threads and
expecting anything other than process termination is wrong code.
This was the general rule:
* You can use the DLL CRT on any thread without a leak.
* If your application code (NOT DLL code) uses the static CRT on
a thread that has NOT been started with this CRT's beginthread[ex]
or that has been ended prematurely by ExitThread(), there will
be a small memory leak.
But dont forget: whenever a thread is ended through TerminateThread(),
there will be enormous leaks (regardless of CRT version and usage)
and probably unsignalled events, locked critical sections and similar
nasty things, all in all introducing undefined behaviour for most
programs.
> On the other hand you say:
> "If you are using the dll version of CRT (msvc*.dll), there won't be any leak.
> See the implementation of _DllMainCRTStartup in CRT\src\ crtdll.c.
> If you are using the static version of crt (libc or libcmt) there will be
> leak."
This was under the assumption that the thread which executed CRT
code has not been created through the CRT's beginthread[ex] or has
been ended prematurely by ExitThread().
(this is the situation from my initial posting)
> What happens if I use beginthread and crt (libc or libcmt) ?
IMHO using beginthread() + libc (NOT libcmt) is only for experts
who know exactly what their code does and what the CRT source
does, under very exotic and allmost abstruse circumstances.
I bet: using libc in MT programs is not supported by MS.
For me this is a good solution.
You are right.
_beginthread /_beginthreadex etc are conditionally declared in process.h
#ifdef _MT
_CRTIMP uintptr_t __cdecl _beginthread (void (__cdecl *) (void *),
unsigned, void *);
_CRTIMP void __cdecl _endthread(void);
_CRTIMP uintptr_t __cdecl _beginthreadex(void *, unsigned,
unsigned (__stdcall *) (void *), void *, unsigned, unsigned *);
_CRTIMP void __cdecl _endthreadex(unsigned);
#endif
So you will get a compiler error if you use them with /ML.