6.7.1 Oops—错误地调用了C r e a t e T h r e a d

来源:互联网 发布:java网上商城 编辑:程序博客网 时间:2024/04/27 15:44
6.7.1 Oops—错误地调用了C r e a t e T h r e a d
也许你想知道,如果调用C r e a t e T h r e a d,而不是调用C / C + +运行期库的_ b e g i n t h r e a d e x来创
建新线程,将会发生什么情况。当一个线程调用要求t i d d a t a结构的C / C + +运行期库函数时,将
会发生下面的一些情况(大多数C / C + +运行期库函数都是线程安全函数,不需要该结构)。首
先, C / C + +运行期库函数试图(通过调用T l s G e t Va l u e )获取线程的数据块的地址。如果返回
N U L L作为t i d d a t a块的地址,调用线程就不拥有与该地址相关的t i d d a t a块。这时,C / C + +运行期
库函数就在现场为调用线程分配一个t i d d a t a块,并对它进行初始化。然后该t i d d a t a块(通过
T l s S e t Va l u e)与线程相关联。此时,只要线程在运行,该t i d d a t a将与线程待在一起。这时,
C / C + +运行期库函数就可以使用线程的t i d d a t a块,而且将来被调用的所有C / C + +运行期函数也
能使用t i d d a t a块。
当然,这看来有些奇怪,因为线程运行时几乎没有任何障碍。不过,实际上还是存在一些
问题。首先,如果线程使用C / C + +运行期库的s i g n a l函数,那么整个进程就会终止运行,因为
结构化异常处理帧尚未准备好。第二,如果不是调用_ e n d t h r e a d e x来终止线程的运行,那么数
据块就不会被撤消,内存泄漏就会出现(那么谁还为使用C r e a t e T h r e a d函数创建的线程来调用
_ e n d t h r e a d e x呢?)。
注意如果程序模块链接到多线程D L L版本的C / C + +运行期库,那么当线程终止运行
并释放t i d d a t a块(如果已经分配了t i d d a t a块的话)时,该运行期库会收到一个
D L L T H R E A D D E TA C H通知。尽管这可以防止t i d d a t a块的泄漏,但是强烈建议使用
_ b d g i n t h r e a d e x而不是使用C r e a t e t h r e a d来创建线程。
原创粉丝点击