///////////////////////////////关于 CreateThread 的问题////////////////////////////
1、CreateThread 函数是用来创建线程的 Windows 函数。如果编写 C/C++ 代码,不应该调用 CreateThread ,应该使用 Visual C++ 运行期库函数 _beginthreadex 。
2、内存泄漏
当一个线程调用要求 tiddata 结构的 C/C++ 运行期库函数时,将会发生下面的一些情况(大多数 C/C++ 运行期库函数都是线程安全函数,不需要该结构):
1)首先, C/C++ 运行期库函数试图(通过调用 TlsGetValue )获取线程的数据块的地址。如果返回 NULL 作为 tiddata 块的地址,调用线程就不拥有与该地址相关的 tiddata 块
2)这时,C/C++ 运行期库函数就在现场为调用线程分配一个 tiddata 块,并对它进行初始化。然后该 tiddata 块(通过 TlsSetValue )与线程相关联
3)此时,只要线程在运行,该 tiddata 将与线程待在一起。这时,C/C++ 运行期库函数就可以使用线程的 tiddata 块,而且将来被调用的所有 C/C++ 运行期函数也能使用 tiddata 块
这看起来没有任何问题,但实际有一些问题。
1)首先,如果线程使用 C/C++ 运行期库的 signal 函数,那么整个进程就会终止运行,因为结构化异常处理帧尚未准备好
2)如果不是调用 _endthreadex 来终止线程的运行,那么数据块就不会被撤消,内存泄漏就会出现
注意:如果程序模块链接到多线程 DLL 版本的 C/C++ 运行期库,那么当线程终止运行并释放 tiddata 块时(如果已经分配了tiddata 块),该运行期库会收到一个 DLL_THREAD_DETACH 通知。尽管这可以防止 tiddata 块的泄漏,但是强烈建议使用 _bdginthreadex 而不是使用 CreateThread 来创建线程。
/////////////////////////////////关于 _beginthread 的问题/////////////////////
_beginthread 是 C/C++ 运行库函数
创建这个函数的目的是用来执行 _beginthreadex。但 _beginthread 函数的参数比较少,因此比 _beginthreadex 函数受到更大的限制。比如,用 _beginthread 就无法创建带有安全属性的新线程,无法创建暂停的线程,也无法获得线程的 ID 值。
////////////////////////////////AfxCreateThread////////////////////////
这个函数没有用过,也不没有见过。不会是程序员自定义的函数吧。也可能是MFC函数,因为MFC我也不熟悉。