三者的声明如下:
uintptr_t _beginthread(
void( *start_address )( void * ),
unsigned stack_size,
void *arglist
);
uintptr_t _beginthreadex(
void *security,
unsigned stack_size,
unsigned ( *start_address )( void * ),
void *arglist,
unsigned initflag,
unsigned *thrdaddr
);
HANDLE WINAPI CreateThread(
__in LPSECURITY_ATTRIBUTES lpThreadAttributes,
__in SIZE_T dwStackSize,
__in LPTHREAD_START_ROUTINE lpStartAddress,
__in LPVOID lpParameter,
__in DWORD dwCreationFlags,
__out LPDWORD lpThreadId
);其实在Windows平台,创建线程只能通过调用CreatetThread来创建线程。
前二者之所以存在,是因为MS为了支持大把的C函数也不得不加入一个C运行时库,当然这个C库是需要MS重构下的。这里面最复杂就是多线程方面的事情了,因为原来的C运行库基本没有多线程的概念的。
_beginthread和_beginthreadex的除了参数的个数不同外,还有以下三点不同:
线程入口函数的调用方式不一样,前者的入口函数调用方式为__cdecl,而后者为__stdcall。二者的差别是比较明显的,且前者的入口函数没有返回值,后者有返回值。
_beginthread不支持安全属性,关于安全属性可以在网上搜索相关的知识。
_beginthreadex返回线程的句柄,函数会返回线程的句柄,这个句柄在线程退出后,需要程序员自己关闭。另外,_beginthread函数创建的线程在执行后,会自动终止。
那如何选择使用哪一个呢?
如何编写的代码中使用了C库的函数(没有调用C库函数也是有可能导入C库),那么应该使用_beginthreadex函数。另外,如果要获取创建的线程的句柄和ID,或者要以SUSPEND的方法创建线程,则需要调用_beginthreadex。
如果线程中依赖了C库而直接使用CreateThread来创建线程则会导致内存泄漏。
_beginthread相当于如下代码:(CloseHandle)(HANDLE)_beginthreadex( NULL, 0, &SecondThreadFunc, NULL, 0, NULL);
而_beginthread则可以简单的认为是“发射后不管”的线程(不需要人工调用CloseHandle来关闭线程句柄)。
而这两个函数最终都是调用CreateThread来创建线程的。