无论如何在 Win32 API 中动态释放线程本地存储?
Posted
技术标签:
【中文标题】无论如何在 Win32 API 中动态释放线程本地存储?【英文标题】:Is there anyway to dynamically free thread-local storage in the Win32 APIs? 【发布时间】:2010-07-13 21:34:43 【问题描述】:我需要在跨平台项目中使用线程本地存储。在 *IX 下,我使用 pthreads 并且可以避免内存泄漏,这要归功于作为 pthread_key_create
的第二个参数传递的好的析构函数指针,但在 Windows 中 TlsAlloc
没有这样的东西。我也找不到在线程退出时调用任何函数的一般位置(否则我会自制一些在退出时调用的函数指针列表)。
目前看来,我基本上有一种情况,为了实际使用线程本地存储,我需要在堆上分配我自己的空间并将指针传递给TlsSetValue
,但是如果线程退出......我无法确保内存被释放(除了有人在线程函数结束时明确调用TlsGetValue
和delete
/free
/HeapFree
/etc。
有人知道更好的方法吗?
【问题讨论】:
你的线程是如何退出的?正常的方法是在你的 threadproc 返回之前进行清理。 【参考方案1】:即使线程已终止,您也可以为自己获得一个不错的“终结器”来摆脱特定于线程的资源:使用RegisterWaitForSingleObject
等待复制(通过DuplicateHandle
)线程句柄的 - 你必须使用克隆的句柄,导致注册的等待不能处理句柄no pun有意关闭。
使用堆分配的结构/记录来保存最终资源、等待的句柄和等待句柄本身,导致 终结器将在系统线程池中运行,而不是在最终线程中运行(到时候它已经死了)。并且不要忘记敲定终结器 :)
【讨论】:
【参考方案2】:在线程退出时调用 DLL (DLLmain
) 的入口点,原因码为 DLL_THREAD_DETACH
。编写一个跟踪函数以在线程退出时调用的 DLL 相当简单。
或者,使用Boost.Thread 和boost::this_thread::at_thread_exit
函数来注册要在线程退出时调用的函数,或者使用boost::thread_specific_ptr
来完全包装TLS 用法。
【讨论】:
以上是关于无论如何在 Win32 API 中动态释放线程本地存储?的主要内容,如果未能解决你的问题,请参考以下文章