Goo*_*ose 6 c++ dll multithreading static-libraries thread-local-storage
我有一个由许多DLL文件组成的游戏.其中一些DLL链接到相同的静态库(LIB).
所以像这样:
Game.exe -> Root.dll -> Child.dll
| |
| '-> Common.lib (contains __declspec(thread))
|
'-> Common.lib (contains __declspec(thread))
Run Code Online (Sandbox Code Playgroud)
Root.dll加载静态链接Common.lib的Child.dll.Root还静态链接Common.lib.因为Common是静态链接的,所以它会直接编译到加载dll中(例如Root和Child).
Common.lib包含使用线程本地存储(TLS)的变量.
__declspec(thread) static void* s_threadValues[PlatformThreadSlotsMax];
Run Code Online (Sandbox Code Playgroud)
这会导致一些有问题的行为:Root.dll和Child.dll每个都包含一个不同的TLS数据实例(s_threadValues).即使在同一个线程上,如果Root.dll调用Common.lib中定义的函数,如果从Child.dll调用相同的函数,则s_threadValues的值将与其值不同.
由于两个DLL都是从同一个线程访问这个TLS,我希望共享TLS,但事实并非如此.
现在,如果我将Common.lib更改为动态链接(例如Common.dll),则不会再出现此问题:对于Root.dll和Child.dll,s_threadValues是相同的.
这是预期的行为吗?无论如何在动态库之间共享静态库中定义的TLS共享使用它吗?
这完全正常.每个DLL都有自己的库代码和数据副本.它自己的线程本地状态.
您可以通过假设它按照您预期的方式工作来解释这一点.然后两个DLL可能会意外地在不同的DLL之间共享自己的线程局部变量.显然这将是灾难性的.它无法以这种方式工作,因为没有机制可以跨模块共享TLS实例.槽索引有意保持模块专用,没有机制来获取__declspec(线程)变量的槽索引.显式调用TlsAlloc()并共享索引将是一种解决方法.不要去那里.
| 归档时间: |
|
| 查看次数: |
2148 次 |
| 最近记录: |