Discussion:
Win32 Thread or _threadstartex'
(too old to reply)
Ron James
2003-07-03 01:34:12 UTC
Permalink
During the course of debugging a thread memory leak, I
wrote this trivial program. It's based on an MFC Dialog
based wizard generated program. it doesn't do much of
course, and doesn't leak memory, but what interests me is
the DEBUG Output window, a sample of which follows.

Question. Why are some threads labelled 'Win32 Thread'
and others '_threadstartex'. Are they really different in
some way? I want to use MFC classes in the thread. Will
all threads support MFC classes?

Thanks.

The thread 'Win32 Thread' (0xd34) has exited with code 0
(0x0).
The thread 'Win32 Thread' (0x6d8) has exited with code 0
(0x0).
The thread 'Win32 Thread' (0x1198) has exited with code 0
(0x0).
The thread '_threadstartex' (0x18f8) has exited with code
0 (0x0).
The thread 'Win32 Thread' (0x8c8) has exited with code 0
(0x0).
The thread 'Win32 Thread' (0x18c4) has exited with code 0
(0x0).
The thread 'Win32 Thread' (0x7f4) has exited with code 0
(0x0).
The thread 'Win32 Thread' (0x400) has exited with code 0
(0x0).
The thread '_threadstartex' (0x1810) has exited with code
0 (0x0).
The thread 'Win32 Thread' (0xaa8) has exited with code 0
(0x0).
The thread 'Win32 Thread' (0x1814) has exited with code 0
(0x0).
The thread 'Win32 Thread' (0x190c) has exited with code 0
(0x0).
The program '[6104] testThread.exe: Native' has exited
with code 0 (0x0).


// Button Handler
void CtestThreadDlg::OnBnClickedTestthread()
{
::AfxBeginThread( ThreadFunction, GetSafeHwnd() );
}

// Handle WM_THREADEND message
LRESULT CtestThreadDlg::OnThreadEnd(WPARAM wParam, LPARAM
lParam) {
static int iCount = 10;
if ( --iCount ) {
::AfxBeginThread( ThreadFunction,
GetSafeHwnd() );
}
return 0L;
}

// Static Thread function
UINT CtestThreadDlg::ThreadFunction( LPVOID lParam ) {
HWND hWnd = static_cast<HWND>( lParam );

::Sleep(250);
// Notify the creating window that we've finished
::PostMessage( hWnd, WM_THREADEND, 0, 0 );
return 0;
}
Ilia
2003-07-03 13:28:09 UTC
Permalink
Sure while in debug mode the VC will trace these. And you are wondering why
once it's "Win32 Thread" and another time '_threadstartex'. And also does
all treads support MFC classes.

So, '_threadstartex' apears because the thread was created using the MT CRT
function _beginthreadex. It actually calls CreateThread in it, with a
"small" difference that it allocates memory itself explicidly for the
parameters of CreateThread, it calls CreateThread with an CRT internally
defined function _threadstartex, which runs the startupaddress given to
_begintheradex - and this is very easy to be seen in crt source code.

AfxBeginThread uses _beginthreadex to start a thread. About the question -
will all threads support MFC - yes, but you will be more save however if you
use AfxBeginThread ot CWinThread when using mfc.

_beginthreadex you should use whenever you plan to call CRT - which happens
virtually always...

Of cource, in general when you use MFc in an multithreaded application there
will be some pain - like you cannot freely use a nonstatic member function
as a theread entry point, and this is understandible, because thread
creation routines does not have the hint about "so what is the this pointer
value??" hence, they cannot call non-tatic members (whell they would call if
you are some almighty bad hacker - passing an addres of a nonstatic member -
reinterpret_casted to thread entry routine, but the this will be null yet,
you violation will take place). So static members ot global functions are
the "standert way".

Luck!
Ilia
Post by Ron James
During the course of debugging a thread memory leak, I
wrote this trivial program. It's based on an MFC Dialog
based wizard generated program. it doesn't do much of
course, and doesn't leak memory, but what interests me is
the DEBUG Output window, a sample of which follows.
Question. Why are some threads labelled 'Win32 Thread'
and others '_threadstartex'. Are they really different in
some way? I want to use MFC classes in the thread. Will
all threads support MFC classes?
Thanks.
The thread 'Win32 Thread' (0xd34) has exited with code 0
(0x0).
The thread 'Win32 Thread' (0x6d8) has exited with code 0
(0x0).
The thread 'Win32 Thread' (0x1198) has exited with code 0
(0x0).
The thread '_threadstartex' (0x18f8) has exited with code
0 (0x0).
The thread 'Win32 Thread' (0x8c8) has exited with code 0
(0x0).
The thread 'Win32 Thread' (0x18c4) has exited with code 0
(0x0).
The thread 'Win32 Thread' (0x7f4) has exited with code 0
(0x0).
The thread 'Win32 Thread' (0x400) has exited with code 0
(0x0).
The thread '_threadstartex' (0x1810) has exited with code
0 (0x0).
The thread 'Win32 Thread' (0xaa8) has exited with code 0
(0x0).
The thread 'Win32 Thread' (0x1814) has exited with code 0
(0x0).
The thread 'Win32 Thread' (0x190c) has exited with code 0
(0x0).
The program '[6104] testThread.exe: Native' has exited
with code 0 (0x0).
// Button Handler
void CtestThreadDlg::OnBnClickedTestthread()
{
::AfxBeginThread( ThreadFunction, GetSafeHwnd() );
}
// Handle WM_THREADEND message
LRESULT CtestThreadDlg::OnThreadEnd(WPARAM wParam, LPARAM
lParam) {
static int iCount = 10;
if ( --iCount ) {
::AfxBeginThread( ThreadFunction,
GetSafeHwnd() );
}
return 0L;
}
// Static Thread function
UINT CtestThreadDlg::ThreadFunction( LPVOID lParam ) {
HWND hWnd = static_cast<HWND>( lParam );
::Sleep(250);
// Notify the creating window that we've finished
::PostMessage( hWnd, WM_THREADEND, 0, 0 );
return 0;
}
Ilia Murjev
2003-07-03 22:29:30 UTC
Permalink
it's just that you are informed when you exit CreateThread's entrypoint
function, and againf when exiting _beginthreadex' one, which is
_threadstartex... what else,
if you want to know much more, you have source and browse info of mfc and
crt, go step into, you'll see what is going on it will take just a few
minues...
Ilia,
many thanks for your reply. But I still don't understand
why some threads are labelled '_threadstartex' and some
are labelled 'Win32 Thread'. ALL my threads were created
using AfxBeginThread. I appreciate that AfxBeginThread
calls _beginthreadex, but since all my threads were
created the same way shouldn't they all have the same
name? I'm only getting 1 exit message per thread - it's
not that I'm seeing the CRT thread exit message AND the
AfxBeginThread exit message.
Thanks again
-----Original Message-----
Sure while in debug mode the VC will trace these. And you
are wondering why
once it's "Win32 Thread" and another
time '_threadstartex'. And also does
all treads support MFC classes.
So, '_threadstartex' apears because the thread was
created using the MT CRT
function _beginthreadex. It actually calls CreateThread
in it, with a
"small" difference that it allocates memory itself
explicidly for the
parameters of CreateThread, it calls CreateThread with an
CRT internally
defined function _threadstartex, which runs the
startupaddress given to
_begintheradex - and this is very easy to be seen in crt
source code.
AfxBeginThread uses _beginthreadex to start a thread.
About the question -
will all threads support MFC - yes, but you will be more
save however if you
use AfxBeginThread ot CWinThread when using mfc.
_beginthreadex you should use whenever you plan to call
CRT - which happens
virtually always...
Of cource, in general when you use MFc in an
multithreaded application there
will be some pain - like you cannot freely use a
nonstatic member function
as a theread entry point, and this is understandible,
because thread
creation routines does not have the hint about "so what
is the this pointer
value??" hence, they cannot call non-tatic members (whell
they would call if
you are some almighty bad hacker - passing an addres of a
nonstatic member -
reinterpret_casted to thread entry routine, but the this
will be null yet,
you violation will take place). So static members ot
global functions are
the "standert way".
Luck!
Ilia
Post by Ron James
During the course of debugging a thread memory leak, I
wrote this trivial program. It's based on an MFC Dialog
based wizard generated program. it doesn't do much of
course, and doesn't leak memory, but what interests me
is
Post by Ron James
the DEBUG Output window, a sample of which follows.
Question. Why are some threads labelled 'Win32 Thread'
and others '_threadstartex'. Are they really different
in
Post by Ron James
some way? I want to use MFC classes in the thread.
Will
Post by Ron James
all threads support MFC classes?
Thanks.
The thread 'Win32 Thread' (0xd34) has exited with code 0
(0x0).
The thread 'Win32 Thread' (0x6d8) has exited with code 0
(0x0).
The thread 'Win32 Thread' (0x1198) has exited with code
0
Post by Ron James
(0x0).
The thread '_threadstartex' (0x18f8) has exited with
code
Post by Ron James
0 (0x0).
The thread 'Win32 Thread' (0x8c8) has exited with code 0
(0x0).
The thread 'Win32 Thread' (0x18c4) has exited with code
0
Post by Ron James
(0x0).
The thread 'Win32 Thread' (0x7f4) has exited with code 0
(0x0).
The thread 'Win32 Thread' (0x400) has exited with code 0
(0x0).
The thread '_threadstartex' (0x1810) has exited with
code
Post by Ron James
0 (0x0).
The thread 'Win32 Thread' (0xaa8) has exited with code 0
(0x0).
The thread 'Win32 Thread' (0x1814) has exited with code
0
Post by Ron James
(0x0).
The thread 'Win32 Thread' (0x190c) has exited with code
0
Post by Ron James
(0x0).
The program '[6104] testThread.exe: Native' has exited
with code 0 (0x0).
// Button Handler
void CtestThreadDlg::OnBnClickedTestthread()
{
::AfxBeginThread( ThreadFunction, GetSafeHwnd() );
}
// Handle WM_THREADEND message
LRESULT CtestThreadDlg::OnThreadEnd(WPARAM wParam,
LPARAM
Post by Ron James
lParam) {
static int iCount = 10;
if ( --iCount ) {
::AfxBeginThread( ThreadFunction,
GetSafeHwnd() );
}
return 0L;
}
// Static Thread function
UINT CtestThreadDlg::ThreadFunction( LPVOID lParam ) {
HWND hWnd = static_cast<HWND>( lParam );
::Sleep(250);
// Notify the creating window that we've finished
::PostMessage( hWnd, WM_THREADEND, 0, 0 );
return 0;
}
.
Joseph M. Newcomer
2003-07-03 19:55:40 UTC
Permalink
I've seen this, and decided it was noise, so I've ignored it. No harm has come to me.

A thread will support MFC if you start it with AfxBeginThread. Do not use _beginthread(ex)
or ::CreateThread.
joe
Post by Ron James
During the course of debugging a thread memory leak, I
wrote this trivial program. It's based on an MFC Dialog
based wizard generated program. it doesn't do much of
course, and doesn't leak memory, but what interests me is
the DEBUG Output window, a sample of which follows.
Question. Why are some threads labelled 'Win32 Thread'
and others '_threadstartex'. Are they really different in
some way? I want to use MFC classes in the thread. Will
all threads support MFC classes?
Thanks.
The thread 'Win32 Thread' (0xd34) has exited with code 0
(0x0).
The thread 'Win32 Thread' (0x6d8) has exited with code 0
(0x0).
The thread 'Win32 Thread' (0x1198) has exited with code 0
(0x0).
The thread '_threadstartex' (0x18f8) has exited with code
0 (0x0).
The thread 'Win32 Thread' (0x8c8) has exited with code 0
(0x0).
The thread 'Win32 Thread' (0x18c4) has exited with code 0
(0x0).
The thread 'Win32 Thread' (0x7f4) has exited with code 0
(0x0).
The thread 'Win32 Thread' (0x400) has exited with code 0
(0x0).
The thread '_threadstartex' (0x1810) has exited with code
0 (0x0).
The thread 'Win32 Thread' (0xaa8) has exited with code 0
(0x0).
The thread 'Win32 Thread' (0x1814) has exited with code 0
(0x0).
The thread 'Win32 Thread' (0x190c) has exited with code 0
(0x0).
The program '[6104] testThread.exe: Native' has exited
with code 0 (0x0).
// Button Handler
void CtestThreadDlg::OnBnClickedTestthread()
{
::AfxBeginThread( ThreadFunction, GetSafeHwnd() );
}
// Handle WM_THREADEND message
LRESULT CtestThreadDlg::OnThreadEnd(WPARAM wParam, LPARAM
lParam) {
static int iCount = 10;
if ( --iCount ) {
::AfxBeginThread( ThreadFunction,
GetSafeHwnd() );
}
return 0L;
}
// Static Thread function
UINT CtestThreadDlg::ThreadFunction( LPVOID lParam ) {
HWND hWnd = static_cast<HWND>( lParam );
::Sleep(250);
// Notify the creating window that we've finished
::PostMessage( hWnd, WM_THREADEND, 0, 0 );
return 0;
}
Joseph M. Newcomer [MVP]
email: ***@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
Loading...