boost::thread_specific_ptr在Windows下可能导致内存泄露

boost::thread_specific_ptr用于定义线程局部变量,根据这个类的定义,当一个线程结束的时候,与之相关的变量都会被释放。然而,这个规则并不是在所有情况下都适用。在boost::thread_specific_ptr的文档中有这么一句话:

Note: on some platforms, cleanup of thread-specific data is not performed for threads created with the platform’s native API. On those platforms such cleanup is only done for threads that are started with boost::thread unless boost::on_thread_exit() is called manually from that thread.

这里的“some platforms”指的就是Windows(不明白为什么boost不在文档中明确说明,这样可以让Windows程序员少碰壁)。在这个平台下,只有通过boost::thread启动的线程才会在结束的时候释放boost::thread_specific_ptr中的变量,通过其它方式启动的线程则要主动调用boost::on_thread_exit函数才能释放这些变量。所以,如果非boost::thread线程访问了boost::thread_specific_ptr,又没有调用boost::on_thread_exit,就会造成内存泄露。

避免这个问题的方法就是尽量使用boost::thread启动线程,这是最省事的方法。然而并不是所有情况都能使用boost::thread,这时就要按照文档说的主动去调用boost::on_thread_exit了。这是一个非公开的方法,它的声明位于boost\thread\detail\tss_hooks.hpp

最坏的情况是,线程是由第三方库启动的,并且无法修改这个库的源码,或者修改的代价很高。在这种情况下,只能避免让这些线程去访问boost::thread_specific_ptr。