您的位置:首页 > 其它

Windows 线程创建方式的比较

2016-07-14 13:08 447 查看
进行 Windows 编程时,常需要涉及多线程编程,以下是 Windows 提供的关于创建线程的3个API。

由于工作繁忙,还未来得及编辑完本篇博客,但是基本内容已经讲清楚,如有疑问,可自行查阅 MSDN。如再有时间,将尽快补全。

一、 函数原型

CreateThread

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


__beginthread

uintptr_t _beginthread(
void( *start_address )( void * ),
unsigned stack_size,
void *arglist
);


_beginthreadex

uintptr_t _beginthreadex(
void *security,
unsigned stack_size,
unsigned ( *start_address )( void * ),
void *arglist,
unsigned initflag,
unsigned *thrdaddr
);


二、三者之间的差别

CreateThread 不会创建线程局部数据 tiddata,用于存储CRT运行时可能产生的错误 ( 存储在 errno 变量之间,对于多线程来说,是个全局共享变量,有数据竞争问题 )

但是,_beginthread 和 _beginthreadex 两个函数会在真正创建一个线程之前,先创建一个线程局部资源区 tiddata。

所以,如果线程中会使用到 CRT 运行时函数,最好不要使用 CreateThread 创建线程。因为,一旦CRT运行时函数发生异常,通过 GetLastError 获得错误码时,获得的可能是其他线程在使用CRT运行时函数所产生的错误。

_beginthread ,如果线程执行函数返回过快(创建函数还没有返回,线程已经执行完毕),则将导致 _beginthread 返回无效句柄。实际上,_beginthread 并不保证返回有效句柄。

所以 _beginthread 返回的句柄不能用于 WaitForSingleObject 。

注:WaitForSingleObject 是用于检测句柄状态的一个API,在此处可以用于线程同步。

_beginthreadex 可设置线程初始状态,以及是否可以继承性等安全属性。由于本函数返回的句柄 Handle 必须被调用线程关闭 CloseHandle ,所以本函数保证返回一个有效的句柄。

_beginthread 创建的线程执行函数,在 return 时,将自动调用 _endthread(也可以显示调用), 而且 _endthread 会主动 CloseHandle,

所以对于_beginthread 创建的线程句柄,不需要显示的调用 CloseHandle。

_beginthreadex 创建的线程执行函数在 return 时,将自动调用 _endthreadex(也可以显示调用), 而 _endthreadex 并不会主动调用 CloseHandle。

由 _beginthreadex 创建的线程句柄,必要由调用 _beginthreadex 的线程 CloseHandle ,以避免句柄泄露。

主动的显式调用 ExitThread、_endthread 和 _endthreadex 会导致不会调用自动C++类的析构函数,而通过 return 返回的结束线程方式会调用C++类的析构函数

所以通过 return 来结束一个线程吧。

创建线程时,_beginthread 和 _beginthreadex 都可以使用,但是 _beginthread 返回的 Handle 不能通过 WaitForSingleObject 来同步主辅线程。

因为,_beginthread 创建的线程在返回时,会主动调用 CloseHanlde ,所以,如果线程返回过快,就会导致 WaitForSingleObject 无法检测句柄状态(Handle)。

以下这段英文摘自 MSDN:

_endthread calls CloseHandle, destroying the thread object before it can be set to the signaled state ,


所以 WaitForSingleObject , 所以是无法检测到 由 _beginthread 返回的 Handle 的状态的。

综上所述,创建线程的时候,最好不要使用 CreateThread 和 _beginthread 。而尽量使用 _beginthreadex。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: