Existem várias diferenças entre _beginthread()
e _beginthreadex()
. _beginthreadex()
foi feito para agir mais como CreateThread()
(em ambos os parâmetros e como se comporta).
Como Drew Hall menciona, se você estiver usando o tempo de execução C / C ++, deverá usar _beginthread()
/ em _beginthreadex()
vez de, CreateThread()
para que o tempo de execução possa executar sua própria inicialização de encadeamento (configurando o armazenamento local do encadeamento etc.).
Na prática, isso significa que CreateThread()
praticamente nunca deve ser usado diretamente pelo seu código.
Os documentos do MSDN para _beginthread()
/ _beginthreadex()
têm bastante detalhes sobre as diferenças - uma das mais importantes é que, já que o identificador de thread de um thread criado por _beginthread()
é fechado automaticamente pelo CRT quando o thread sai ", se o thread gerado por _beginthread sair rapidamente, o identificador retornado ao chamador de _beginthread pode ser inválido ou, pior, apontar para outro encadeamento ".
Aqui está o que os comentários _beginthreadex()
na fonte do CRT têm a dizer:
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).
Atualização em janeiro de 2013:
O CRT para VS 2012 tem um bit adicional de inicialização realizado em _beginthreadex()
: se o processo for um "aplicativo empacotado" (se algo útil for retornado GetCurrentPackageId()
), o tempo de execução inicializará o MTA no thread recém-criado.