Il existe plusieurs différences entre _beginthread()
et _beginthreadex()
. _beginthreadex()
a été faite à agir plus comme CreateThread()
(dans les deux paramètres et comment il se comporte).
Comme Drew Salle de mentions, si vous utilisez le C/C++ runtime, vous devez utiliser _beginthread()
/_beginthreadex()
au lieu de CreateThread()
, de sorte que l'exécution ait une chance de réaliser son propre thread d'initialisation (mise en place de thread local storage, etc.).
Dans la pratique, cela signifie qu' CreateThread()
doit à peu près jamais être utilisé directement par votre code.
La MSDN documents pour l' _beginthread()
/_beginthreadex()
ont un peu de détail sur les différences - l'un des plus important est que, depuis le fil de la poignée pour un thread créé par _beingthread()
se ferme automatiquement par le CRT lorsque le thread s'arrête, "si le thread généré par _beginthread quitte rapidement, le handle retourné à l'appelant de _beginthread peut-être pas valide ou, pire, point à un autre thread".
Voici ce que les commentaires de l' _beginthreadex()
dans la source CRT ont à dire:
Differences between _beginthread/_endthread and the "ex" versions:
1) _beginthreadex takes the 3 extra parameters to CreateThread
which are lacking in _beginthread():
A) security descriptor for the new thread
B) initial thread state (running/asleep)
C) pointer to return ID of newly created thread
2) The routine passed to _beginthread() must be __cdecl and has
no return code, but the routine passed to _beginthreadex()
must be __stdcall and returns a thread exit code. _endthread
likewise takes no parameter and calls ExitThread() with a
parameter of zero, but _endthreadex() takes a parameter as
thread exit code.
3) _endthread implicitly closes the handle to the thread, but
_endthreadex does not!
4) _beginthread returns -1 for failure, _beginthreadex returns
0 for failure (just like CreateThread).
Mise À Jour De Janvier 2013:
Le CRT pour VS 2012 a un bit supplémentaire de l'initialisation effectuée en _beginthreadex()
: si le processus est un "emballé application" (si quelque chose d'utile est retourné à partir de GetCurrentPackageId()
) l'exécution d'initialiser la MTA sur le nouveau thread.