无论如何在 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,但是如果线程退出......我无法确保内存被释放(除了有人在线程函数结束时明确调用TlsGetValuedelete/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 中动态释放线程本地存储?的主要内容,如果未能解决你的问题,请参考以下文章

如何检查用户是不是在win32中具有本地管理员权限

win32 api - 如何检查远程机器上的用户权限

Win32 API 多线程播放 .wav 文件没有延迟

win32 相关同步api

win32 相关同步api

win32API多线程编程