oh sorry, i see it ......:)
oh sorry, i see it ......:)
If this is the case, then why would anybody ever use CreateThread()? If no components of the STL can be used in a thread created with CreateThread(), doesn't that render it rather useless except for situations in which the thread performs extremely simple tasks? And if it's useless, then why did MS bother including it in the Windows API?Quote:
Yes, exactly that. The C and C++ libraries need some additional housekeeping when starting and ending threads, so you need to use _beginthread[ex] and _endthread[ex], which perform this housekeeping.
>> And if it's useless, then why did MS bother including it in the Windows API? <<
What do you think _beginthreadex() calls? _beginthreadex() is part of the C run-time library, CreateThread is the operating system function. Many applications don't even use C/C++, let alone the C run-time library.
>> If this is the case, then why would anybody ever use CreateThread()? <<
Often, you are only creating a few worker threads. In this case the small (4KB per thread according to some reports) memory leak is insignificant. Other applications do not destory their threads at all.
According to this informative post on the issue, only certain functions will trigger the memory leak.
And this what MSDN says on the matter.Quote:
_beginthread vs CreateThread
To wrap this up, if CreateThread/ExitThread (or a simple return)
is used in an app which uses parts of the C MT-RTL that needs
per-thread data, memory leaks will occur.
Some of the goodies inside the MT C-RTL's per-thread data struct are:
Floating Point data segment
rand() seed value
ptr to strtok() token
ptr to wcstok() token
ptr to _mbstok() token
ptr to strerror()/_strerror() buff
ptr to tmpnam() buffer
ptr to _wtmpnam() buffer
ptr to tmpfile() buffer
ptr to _wtmpfile() buffer
ptr to asctime() buffer
ptr to _wasctime() buffer
ptr to gmtime() structure
ptr to ecvt()/fcvt buffer
stuff for signal handling and fp exceptions
per-thread data needed by C++ Exception Handling
So, if you never use anything of the above, you would probably be
sure that you're not leaking memory. Or, if using these things,
you should call _endthreadex() instead of ExitThread().
BTW, you should always use _beginthreadex() instead of _beginthread()
since _beginthread() is old, unreliable (it has a thread handle
race condition) and lacks important parameters you'll need for
any serious MT app development.
In summary, if you are creating a half-dozen worker threads or even a couple of hundred that won't be destroyed, then don't worry about using CreateThread(). On the other hand, if you are creating a temporary thread to handle every request in a web server, you better think about it.Quote:
Originally Posted by MSDN CreateThread
Great link, thanks :)
>>Often, you are only creating a few worker threads. In this case the small (4KB per thread according to some reports) memory leak is insignificant, if the threads are destroyed at all.
Since _beginthreadex() has all the same functionality as CreateThread() and doesn't have the potential memory leak, doesn't that mean there is really no reason at all to use CreateThread()? Or is it a speed/performance thing...
>> Compiler/IDE: MSVC++ 6.0 Pro Edition
Then you have the MS-CRT source code, including beginthreadex() :)
Take a look-see, it's nothing fancy.
As a side note, STLport claims that their implementation of the C++ Standard Library is thread safe. Has anyone tested and confirmed/refuted this?
Testing for thread safety is extremely hard. Mostly you can only design and hope. ;)
I see absolutely no reason to call CreateThread when you can call _beginthreadex. I wonder, though, will there be a leak if I call CreateThread and ExitThread or only if I call _beginthreadex and then ExitThread?
Certainly hard, but at least to some extent it can be done (i.e. you can prove it isn't thread safe, but not so easily the other way around). :)
Perhaps this is a better wording of the question: Has anybody had experience writing multi-threaded code with STLport, and if so, how well did it behave?
I have, and yes it's thread safe (I've yet to expose a bug atleast) - but not "thread safe" in the way that some readers are probably thinking.
- simultaneous read access to the same container from within separate threads is safe;
- simultaneous access to distinct containers (not shared between threads) is safe;
- user must provide synchronization for all accesses if any thread may modify shared container.
Yeah, that's what I expected for "thread-safety". Good to know it works as advertised.
>>Then you have the MS-CRT source code, including beginthreadex()
Uh.. what exactly is the MS-CRT? MS component runtime? Cathode ray tube? Cryptographical relay team? Cowardly rebellious tuna? :confused:
Apparently so :(Quote:
will there be a leak if I call CreateThread and ExitThread or only if I call _beginthreadex and then ExitThread?
But how can this memory get allocated if _beginthreadex() isn't used
in the first place?
Well, for starters, any RTL function that needs to access "global"
data (e.g., errno) contained in the per-thread data struct, will first
check if the struct is allocated; and if not, allocate memory for it, itself.
CRT stands for C RunTime as defined by the ISO C standard, and MS-CRT is Microsoft's implementation of the same.
Ok, thanks. I'll take a look at it.
>> I see absolutely no reason to call CreateThread when you can call _beginthreadex.
If you don't use or link to the CRT, that's a good reason to use CreateThread :)
>> I wonder, though, will there be a leak if I call CreateThread and ExitThread or only if I call _beginthreadex and then ExitThread?
The memory which is potentially leaked, comes from a per-thread structure that is allocated off the heap. In order to understand when the leak occurs, we need to know (a) when the structure is allocated, and (b) when the structure is free'd.
When is it allocated?
- When _beginthread[ex] is called.
- When any CRT function is called that creates the global structure (so it can use it).
When is it free'd?
- When _endthread[ex] is called.
- When _beginthread[ex] is used, _endthread[ex] is called for you auto-magically.
- When linked to the CRT dynamically,  the structure is free'd. [/edit]
When is memory leaked?
- When linking statically with the CRT -> and CreateThread() is used -> and the thread calls a CRT function that allocates the global structure -> and the thread does not call _endthread[ex].
- When a DLL module calls DisableThreadLibraryCalls() -> then satisfies the first bullet.
I consider that a situation in which you can't call _beginthreadex ;)Quote:
If you don't use or link to the CRT, that's a good reason to use CreateThread