kiv*_*ple 0 c winapi multithreading
TlsAlloc在 WinAPI 中,您可以使用、TlsGetValue和TlsSetValue等函数创建和访问线程本地存储TlsFree。API 假设您将在线程本地存储中存储指针(当然您可以存储size_t转换为指针的整数,但通常我们希望存储更多信息)。因此,可能该内存将由使用该数据的每个线程分配。但问题是如何在线程退出时释放这些内存。
在 pthreads 中,您有一个可选的函数destructor参数pthread_key_create(pthreads 版本TlsAlloc)。但在原始 WinAPI 中TlsAlloc不提供这样的选项。如何仅使用 WinAPI 和纯 C 实现线程本地存储的自定义析构函数(因此没有现代 C++ 线程本地存储支持编译器级别的对象析构函数)?
我正在编写一个普通程序,而不是一个 DLL,所以我不关心“DLL 在程序退出之前卸载,因此析构函数代码变得不可用”的极端情况。我想,我正在寻找一个类似于 的函数atexit,但在线程级别。
在 Windows Vista+ 上,如果切换到光纤本地存储(FLS) 而不是线程本地存储 (TLS),则可以用来FlsAlloc()注册可在线程退出时调用的回调函数。
\n\n应用程序定义的函数。如果 FLS 槽正在使用中,
\nFlsCallback则在纤程删除、线程退出以及释放 FLS 索引时调用。调用函数时指定该函数FlsAlloc。该PFLS_CALLBACK_FUNCTION类型定义了指向此回调函数的指针。FlsCallback是应用程序定义的函数名称的占位符。
请参阅 Raymond Chen 的文章:纤维\xe2\x80\x99t 不再有用;\xe2\x80\x99s 只有一个角由于与纤维无关的原因仍然有用
\n\n\n但 Windows Fiber 的\xe2\x80\x99s 仍然有用:Fiber 销毁回调。
\n...
\n当光纤被破坏时,回调函数被调用。这是 DLL_THREAD_DETACH 的光纤等效项,只不过它\xe2\x80\x99s 不仅仅适用于 DLL。可执行文件也可以使用它。
\n更好的是:当您取消分配光纤本地存储槽时,将为每个现有光纤调用回调。这可以让您在为时已晚之前清理所有每根光纤的数据。
\n...
\n尽管光纤基本上已经死亡,但您可以使用光纤本地存储来获得线程本地存储的改进版本。
\n
如果您不为每个线程创建多个纤程,FLS 的行为将与 TLS 相同,但您将获得销毁回调的额外好处。
\n