_beginthreadex / CreateThread 的用法

来源:互联网 发布:linux的arp表大小 编辑:程序博客网 时间:2024/06/05 12:39

(1)相关背景:
C运行期库中有不少针对全局变量的操作,为了避免各线程同时进行这些操作时而发生冲突,应该确保每个线程都有自己专用的tiddata内存结构来替代这些全局变量,线程结束时也应该释放该tiddata内存。
据侯捷的《Win32多线程程序设计》,场景包括:
(a)使用 malloc() 和free(),或是new和delete
(b)使用stdio.h或io.h里面声明的任何函数
(c)使用浮点变量或浮点运算函数
(d)调用任何一个使用了静态缓冲区的runtime函数,比如:asctime(),strtok()或rand()

(2)C函数使用 tiddata 的内部机制:
C函数如 strtok() 中,先调用 _getptd() 获取相应 tiddata,
而 _getptd()内,TlsGetValue() 若取到则直接返回供使用,
否则先分配,并_initptd()初始化,再调用TlsSetValue()绑定,再返回。

(3)_beginthreadex/_endthreadex 的内部机制:
_beginthreadex()内,预先分配一个tiddata,_initptd()初始化,再传给之后调用的CreateThread(),
_endthreadex()内,_getptd()获取tiddata,_freeptd()释放掉,再调用ExitThread()。

(4)CreateThread/ExitThread 的内部机制:
CreateThread()运行时,不会预先创建并关联 tiddata,直到第一次使用 tiddata 时才被动创建并关联,
之后的多线程能正确运行,但是,线程退出时 ExitThread() 无法释放该内存结构,导致内存泄露。
除非整个程序不调用相关C函数与变量,用CreateThread()才没有任何问题。

(5)个人设想:

CreateThread() / _endthreadex() 方案是否没有问题?
先不理会两者搭配有些怪的问题。

 

_beginthreadex() / _endthreadex() 的正确用法(据MSDN):

unsigned __stdcall ThreadProc(void *param){//... 线程内主体操作_endthreadex(0); //释放 tiddata, 再 ExitThread()return 0;}void main(int argc, char *argv[]){unsigned tid = 0;HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, ThreadProc, NULL, 0, &tid);WaitForSingleObject(hThread, INFINITE); //阻塞等待新线程结束CloseHandle(hThread); //关闭句柄}


 

原创粉丝点击