Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

CreateThread vs. _beginthread

279 views
Skip to first unread message

Lou Bakos

unread,
Mar 12, 1995, 10:49:50 PM3/12/95
to
I am looking for some guidelines about when to use the CreateThread Win32
functions and when to use the _beginthread C runtime functions.

david....@octel.com

unread,
Mar 13, 1995, 6:16:03 AM3/13/95
to
In article <3k0fcu$n...@sun.sirius.com>
louis...@righthinking.com (Lou Bakos) wrote:

> 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.


Carlos Antunes

unread,
Mar 13, 1995, 7:21:51 AM3/13/95
to

In article <3k0fcu$n...@sun.sirius.com>
louis...@righthinking.com (Lou Bakos) wrote:
> I am looking for some guidelines about when to use the CreateThread Win32
> functions and when to use the _beginthread C runtime functions.
>

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. |
+---------------------------------------------------+------------------+

Ron Forrester

unread,
Mar 13, 1995, 4:43:25 PM3/13/95
to
In article <3k1dcv$8...@individual.puug.pt>,
cm...@individual.puug.pt says...

>
>
>In article <3k0fcu$n...@sun.sirius.com>
>louis...@righthinking.com (Lou Bakos) wrote:
>> I am looking for some guidelines about when to use the
CreateThread Win32
>> functions and when to use the _beginthread C runtime
functions.
>>
>
>If you need to link with libmtc.lib ( C runtime functions)
then you should call
>_beginthread.

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

hamilton on BIX

unread,
Mar 14, 1995, 3:38:58 PM3/14/95
to
r...@infograph.com (Ron Forrester) writes:

>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

Torsten Sturm

unread,
Mar 17, 1995, 7:10:10 AM3/17/95
to
r...@infograph.com (Ron Forrester) writes:


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|
|_______________________________________________________________________|

Dan Spalding

unread,
Mar 18, 1995, 3:28:16 PM3/18/95
to
In article <hamilton....@BIX.com>,
hamilton on BIX (hami...@BIX.com) wrote:

: r...@infograph.com (Ron Forrester) writes:
:
: >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.

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=====\
-----------------------------------------------------------------------


John Kepus

unread,
Mar 20, 1995, 2:56:23 PM3/20/95
to
>/ hpcc01:comp.os.ms-windows.programmer.win32 / da...@microsoft.com (Dan Spalding) / 12:28 pm Mar 18, 1995 /

>In article <hamilton....@BIX.com>,
>hamilton on BIX (hami...@BIX.com) wrote:
>: r...@infograph.com (Ron Forrester) writes:
>:
>: >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?
>----------

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 :)

Steve Salisbury

unread,
Mar 21, 1995, 3:37:44 PM3/21/95
to
In article <...> tke...@hpcc01.corp.hp.com (John Kepus) writes:
>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???

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 # |-------------------------------------------------------|

Dan Spalding

unread,
Mar 22, 1995, 9:12:46 PM3/22/95
to
In article <7067...@hpcc01.corp.hp.com>,
John Kepus (tke...@hpcc01.corp.hp.com) wrote:
: 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 :)

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.

Alan Stokes

unread,
Mar 23, 1995, 12:58:32 PM3/23/95
to
In <D5t5A...@microsoft.com> ste...@microsoft.com (Steve Salisbury) writes:
>In article <...> tke...@hpcc01.corp.hp.com (John Kepus) writes:
>>Oh great. Let's see:
>>
>>1) _beginthread
>>2) _beginthreadNT
>>3) _beginthreadex
>>4) CreateThread
>>

>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

Curt Hagenlocher

unread,
Mar 25, 1995, 10:13:05 AM3/25/95
to
al...@rcp.co.uk (Alan Stokes) writes:

>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

Anders Nilsson

unread,
Mar 27, 1995, 3:45:58 AM3/27/95
to
Regarding four way to create a thread

There is also an other method to create a thread, that is using
the CWinThread class in MFC.
I also have had problem to select wich method to use when
creating threads, CreateThread() _beginthread() _beginthreadex()
CWinThread...
Can someone explain when to use which! In the help files there is
a note about that you can't use MCF classes in a thread that is
not creathed with the CWinThread, but when I tested it worked,
but I don't now for how long and if there is some hidden problem
with it.

Is there some good information about threads and processes
someware, or a good book about the subject.

Anders Nilsson

Bill Tierney

unread,
Mar 27, 1995, 9:26:35 PM3/27/95
to era....@memo.ericsson.se
> Can someone explain when to use which! In the help files there is
> a note about that you can't use MCF classes in a thread that is
> not creathed with the CWinThread, but when I tested it worked,
> but I don't now for how long and if there is some hidden problem
> with it.


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

Jim Patterson

unread,
Apr 4, 1995, 3:00:00 AM4/4/95
to
Anders Nilsson (era....@memo.ericsson.se) wrote:
: Regarding four way to create a thread
:
: There is also an other method to create a thread, that is using
: the CWinThread class in MFC.
: I also have had problem to select wich method to use when
: creating threads, CreateThread() _beginthread() _beginthreadex()
: CWinThread...
: Can someone explain when to use which! In the help files there is
: a note about that you can't use MCF classes in a thread that is
: not creathed with the CWinThread, but when I tested it worked,

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

0 new messages