> I am looking for some guidelines about when to use the CreateThread Win32
> functions and when to use the _beginthread C runtime functions.
You _must_ use _beginthread() (or _beginthreadex()) if your
process also calls c runtime functions.
If your process never calls any crt functions (isn't linked
with libcrt or its lik) then use CreateThread().
_beginthread is there because the runtime library's internals
can become corrupted unless it "knows" when a new thread
is created.
I'm sure this is in the documentation somewhere, but
can't find it right now.
If you need to link with libmtc.lib ( C runtime functions) then you should call
_beginthread.
Regards,
Carlos Antunes.
+----------------------------------------------------------------------+
| Once you realize life is meaningless, you can start enjoying it. |
+---------------------------------------------------+------------------+
| Carlos Antunes @ Lisbon/Portugal/European Union | Developing for |
| Phone: +351-1-3975303 Fax: +351-1-3975889 | Win NT & Win 95. |
+---------------------------------------------------+------------------+
I am not familiar with the beginthread* functions, so forgive
me if this is a no brainer -- can you still use the WaitFor*
calls on the handles returned by these functions?
rjf
>I am not familiar with the beginthread* functions, so forgive
>me if this is a no brainer -- can you still use the WaitFor*
>calls on the handles returned by these functions?
Sadly, no! The _endthread routine (which the child thread will pass thru as
it exits) closes the handle to itself that would have been returned by
_beginthread. So you can see there's a race condition here: if you don't
actually enter that WaitForXXX() call in the parent 'till after the child
has already exited, that handle is no longer a valid reference to the child.
Matter of fact, since handle values are reused very quickly by Win32, there's
no telling what that handle might refer to.
This is why I personally do NOT use the MT C run-time library. I stick with
the single-threaded library, call CreateThread directly, and semaphore any
use of non-trivial CRTL routines I suspect might not be re-entrant.
Regards,
Doug Hamilton KD1UJ hami...@bix.com Ph 508-440-8307 FAX 508-440-8308
Hamilton Laboratories, 21 Shadow Oak Drive, Sudbury, MA 01776-3165, USA
Just take a look inside the source of the run time library :
The beginthreadNT sets up a Thread Local Storage
structure, where it stores useful information concerning
the new thread. Then it calls CreateThread from NT API
with a function pointer to an run time internal function under
help of structured execption handling. It then returns the thread
handle whuch it just got from CreateTread.
The internal run time thread function takes some more actions
to store information in the TLS, and then calls the function
pointer provided by the original beginsthreadNT call.
If you don't need specific NT features (security), you can also
call begintread, which simply calls beginthreadNT with
default values.
Hope that helps ...
Torsten
---
_________________________________________________________________________
| |
| Torsten Sturm : Student of Computer Science |
| University of Erlangen-Nuremburg |
| FTP-Administrator for PC / Windows subdirs of ftp.uni-erlangen.de |
| |
| Internet : tns...@cip.informatik.uni-erlangen.de |
| WWW: |
| http://wwwcip.informatik.uni-erlangen.de/user/tnsturm/index.html|
|_______________________________________________________________________|
That statement is true for v1 of the multi-threaded CRT. Because of
those limitations, we added the _beginthreadex() and _endtheadex()
versions to the v2 MT CRT. They closely mimic CreateThread/EndThread,
and you get to do whatever you want with the handles. They also make
sure the CRT knows about the threads so they can be cleaned up properly.
: Regards,
: Doug Hamilton KD1UJ hami...@bix.com Ph 508-440-8307 FAX 508-440-8308
: Hamilton Laboratories, 21 Shadow Oak Drive, Sudbury, MA 01776-3165, USA
:
Hey Doug! You're the reason we added those functions!
;)
dan
--
-----------------------------------------------------------------------
Dan Spalding, aka da...@microsoft.com, aka drspa...@aol.com
Don't you wish that ignorance was painful? ////
(o o)
Not necessarily the opinion of Microsoft /======oOOo=(_)=oOOo=====\
-----------------------------------------------------------------------
Oh great. Let's see:
1) _beginthread
2) _beginthreadNT
3) _beginthreadex
4) CreateThread
Wonderful. Why can't there just be *one* call for creating a #$@%! thread???
-Todd K.
OK! I'm kinda in a bad mood :)
I think the situation is not as grim as it may seem to you.
********
Summary: Generally you should use _beginthreadex() and _endthreadex() (#3).
********
I have never heard of _beginthreadNT (#2). I have no idea where this came
from.
_beginthread() (#1) is obsolete. It's best not use it when writing new
code. We keep it in the C/C++ Run-Time Library for compatibility with
older CRT libraries.
If you are writing an EXE or DLL with Microsoft (Visual) C/C++ v2.0 or
later, just use #3 _beginthreadex. It has the same parameters and
semantics as #4 CreateThread, but it (#3) gives the C run-time library
notification to clean up the per-thread data that the CRTL has to
allocate behind your back.
If you are not linking with C run-time libraries, you would just call #4.
Since #3 and #4 have the same parameters and return values, this is easy.
This is not official technical support but a personal attempt to be helpful.
Thanks,
Steve Salisbury
# Obligatory_ # |-------------------------------------------------------|
# disclaimer_ # | The views expressed in this message are my own and in |
# required by # | no way reflect the views of Microsoft Corporation. |
# my employer # |-------------------------------------------------------|
where did you come up with _beginthreadNT???
there is exactly one api for creating threads: CreateThread. _beginthread
is a way of doing it for the majority of tasks that don't do or need
synchronization based on the thread's lifetime. _beginthreadex is
exactly the same as CreateThread except that it let's the CRT know about
the thread it is creating.
>If you are not linking with C run-time libraries, you would just call #4.
>Since #3 and #4 have the same parameters and return values, this is easy.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Come again? One uses unsigned for everything, the other uses DWORD (=unsigned
long). The prototypes for the thread functions are incompatible. One returns
a HANDLE (a pointer), one an unsigned long. OK, so you can replace one with
the other and get it to compile if you turn off all compiler warnings, but
some people prefer to have reliable, portable, standard C code.
It's a shame that the OS was designed in such a way that no compiler could
allow access to CreateThread - all that is needed is a hook to allow the compiler
to know that a thread is being created in the current process, and that could
be used for other things too by us users. Given that NT doesn't have such a
feature, it seems a bit silly the compiler people don't seem to have talked to
the OS people to manage to get the same prototypes.
--
Alan Stokes (al...@rcp.co.uk)
RCP Consultants Ltd
Didcot, UK
>Come again? One uses unsigned for everything, the other uses DWORD (=unsigned
>long). The prototypes for the thread functions are incompatible. One returns
I don't want to detract from the rest of your article, but in every Win32
compiler that I know about, unsigned (int) is equivalent to (but not
identical to) unsigned long. Both types represent unsigned 32-bit
quantities.
--
Curt Hagenlocher
c...@earthlink.net
c...@netcom.com
I have a little information on this....
It is true that you cannot use SOME MFC classes/functions in a thread
that is not created with CWinThread. For example, the global
function AfxGetMainWnd(), will not work at all in non CWinThread
threads. Generally, you cannot use classes that are part of the
MFC app/mainframe/document/view architecture.
You can, however, use many CObject derived classes, and all of the
collection classes in non CWinThread threads.
One additional note, it seems that you cannot use an MFC CWinThread
thread in an application that doesn't have a CWinApp/CMainFrame
object. I tired to do this in both DLL's (old style) and static
libraries. It doesn't work. I ended up using CreateThread(), which
works quite nicely.
--
Bill Tierney
Basically, CreateThread is the WIn32 API, and so is the lowest common
demoninator. However, if you're using the C RTL or MFC, you will likely
want to use the corresponding thread function for that library as it
will do extra work so that the RTL functions know about the current
thread structure. For example, I think _beginthreadex allocates a
thread-local errno value. Also, _beginthread is apparently obsolete; it
'loses' a handle somewhere, so you should avoid it. (Jeffrey Ritcher
mentions this in "Advanced Windows").
Presumably, if you're using MFC, you may want to use CWinThread instead
of something else. I haven't used it so I don't know the details.
--
Jim Patterson Cognos Incorporated
Sr Consulting Engineer P.O. BOX 9707
UUNET:ji...@cognos.COM 3755 Riverside Drive
PHONE:(613)738-1338 x3385 Ottawa, Ont K1G 3Z4