关于CreateThread和_beginthreadex的区别与联系

来源:互联网 发布:ios看书软件推荐 编辑:程序博客网 时间:2024/05/20 07:58

1.简单来说CreateThread是Windows下用于创建线程的系统API,_beginthreadex则是Visual C++运行时库函数

2._beginthreadex会在内存堆上分配一个与线程相关的数据块,而CreateThread不会分配该数据块

3.如果调用strtok、strerror、gmtime等等,会分配线程相关的数据块。当线程退出时,用_beginthreadex创建的线程会调用_exitthreadex释放该数据块;相反用CreateThread创建的线程并不会调用_exitthreadex,从而导致内存泄露。

具体可以调试到VC++给定的源码进行深入理解。上面提到的数据块,其实就是Windows的线程本地存储器(TLS)的运用。


由于我们在编写C/C++程序时,会调用第3点中涉及到的运行时库函数,所以建议在创建线程的时候不要直接调用CreateThread函数,而是调用_beginthreadex来创建线程。

至于两者的联系,_beginthreadex会调用CreateThread来创建线程实例。

同时最好不会调用_beginthread来创建线程,因为_beginthread参数太少,不能全面设置线程的一些信息。

例如,如果使用_beginthread,就无法创建带有安全属性的新线程,无法创建暂停的线程,也无法获得线程的I D值。_endthread函数的情况与之类似。它不带参数,这意味着线程的退出代码必须硬编码为0。

_endthread函数还存在另一个很难注意到的大问题。在_endthread调用ExitThread之前,它调用CloseHandle。

DWORD dwExitCode;HANDLE handle = _beginthread(...);GetExitCodeThread(handle, &dwExitCode);CloseHandle(handle);
新创建的线程可能在第一个线程调用GetExitCodeThread之前运行、返回和终止。如果出现这种情况,handle中的值将无效,因为_endthread已经关闭了新线程的句柄。不用说,由于相同的原因,对CloseHandle的调用也将失败。

新的_endthreadex函数并不关闭线程的句柄,因此,如果用调用_beginthreadex来取代调用_beginthread,那么上面的代码段将能正确运行。记住,当线程函数返回时, _beginthreadex调用_endthreadex,而_beginthread,则调用_endthread。

原创粉丝点击