windows 解决错误 R6016 - 线程数据空间不足

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21127460/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 11:15:47  来源:igfitidea点击:

Resolving Error R6016 - Not enough space for thread data

windowsmultithreadingvisual-c++-2012

提问by Dev93

My statically-linked Visual C++ 2012 program sporadically generates a CRTL error: "R6016 - Not enough space for thread data".

我的静态链接 Visual C++ 2012 程序偶尔会生成 CRTL 错误:“R6016 - 线程数据空间不足”。

The minimal documentation from Microsoft says this error message is generated when a new thread is spawned, but not enough memory can be allocated for it.

微软的最小文档说这个错误消息是在产生新线程时生成的,但没有足够的内存可以分配给它。

However, my code only explicitly spawns a new thread in a couple of well-defined cases, neither of which are occurring here (although certainly the Microsoft libraries internally spawn threads at well). One user reported this problem when the program was just existing in the background.

但是,我的代码仅在几个明确定义的情况下显式地生成一个新线程,这两种情况都没有发生在这里(尽管 Microsoft 库在内部确实很好地生成了线程)。当程序刚刚存在于后台时,一位用户报告了此问题。

Not sure if it's relevant, but I haven't overridden the default 1MB reserved stack size or heap size, and the total memory in use by my program is usually quite small (3MB-10MB on a system with 12GB actual RAM, over half of which is unallocated).

不确定它是否相关,但我没有覆盖默认的 1MB 保留堆栈大小或堆大小,并且我的程序使用的总内存通常很小(在具有 12GB 实际 RAM 的系统上为 3MB-10MB,超过一半这是未分配的)。

This happens very rarely (so I can't track it down), and it's been reported on more than one machine. I've only heard about this on Windows 8.1, but I wouldn't read too much into that.

这种情况很少发生(所以我无法追踪它),并且已经在不止一台机器上报告过这种情况。我只在 Windows 8.1 上听说过这个,但我不会读太多。

Is there some compiler setting somewhere that might influence this error? Or programming mistake?

是否有一些编译器设置可能会影响此错误?还是编程错误?

采纳答案by Dev93

This turned out to be caused by calling CreateThread rather than _beginthread. Microsoft documentation in the Remarks section states that CreateThread causes conflicts when using the CRT library, and indeed, once we made the change, we never saw that error again.

结果证明这是由调用 CreateThread 而不是 _beginthread 引起的。备注部分中的 Microsoft 文档指出CreateThread 在使用 CRT 库时会导致冲突,事实上,一旦我们进行了更改,我们就再也没有看到该错误。

回答by Stefan Steiger

You have to call TlsAlloc in DllMain if the Windows version is Vista or higher .

如果 Windows 版本是 Vista 或更高版本,则必须在 DllMain 中调用 TlsAlloc。

implicit TLS handling was rewritten in Windows Vista [...] threadprivate and __declspec(thread) should function correctly in run-time loaded DLLs since then.

隐式 TLS 处理在 Windows Vista 中被重写 [...] threadprivate 和 __declspec(thread) 从那时起应该在运行时加载的 DLL 中正常运行。

BOOL APIENTRY DllMain(HINSTANCE hinstDll, DWORD fdwReason,
           LPVOID lpvReserved)
   {
       static BOOL fFirstProcess = TRUE;
       BOOL fWin32s = FALSE;
       DWORD dwVersion = GetVersion();
       static DWORD dwIndex;

       if ( !(dwVersion & 0x80000000) && LOBYTE(LOWORD(dwVersion))<4 )
           fWin32s = TRUE;

       if (dwReason == DLL_PROCESS_ATTACH) {
           if (fFirstProcess || !fWin32s) {
               dwIndex = TlsAlloc();
            }
            fFirstProcess = FALSE;
       }

   }

kb 118816

知识库 118816

When a program is started the size of the TLS is determined by taking into account the TLS size required by the executable as well as the TLS requirements of all other implicitly loaded DLLs. When you load another DLL dynamically with LoadLibrary or unload it with FreeLibrary, the system has to examine all running threads and to enlarge or compact their TLS storage accordingly.

当程序启动时,TLS 的大小是通过考虑可执行文件所需的 TLS 大小以及所有其他隐式加载的 DLL 的 TLS 要求来确定的。当您使用 LoadLibrary 动态加载另一个 DLL 或使用 FreeLibrary 卸载它时,系统必须检查所有正在运行的线程并相应地扩大或压缩它们的 TLS 存储。

Your DLL code should be modified to use such TLS functions as TlsAlloc, and to allocate TLS if the DLL is loaded with LoadLibrary. Or, the DLL that is using __declspec(thread) should only be implicitly loaded into the application.

应修改 DLL 代码以使用诸如 TlsAlloc 之类的 TLS 函数,并在 DLL 使用 LoadLibrary 加载时分配 TLS。或者,使用 __declspec(thread) 的 DLL 应该只隐式加载到应用程序中。

Bottom line: LoadLibrary ain't thread-safe.

底线:LoadLibrary 不是线程安全的。

回答by CelzioBR

I discovered that process is in 32 bit. In this case I increase memory to process with the command

我发现该进程是 32 位的。在这种情况下,我会增加内存以使用命令进行处理

bcdedit /set increaseuserva 3072

bcdedit /set increaseuserva 3072