解决错误R6016 - 没有足够的空间用于线程数据

时间:2014-01-15 01:26:15

标签: windows multithreading visual-c++-2012

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

Microsoft提供的最小文档说明在生成新线程时会生成此错误消息,但是没有为其分配足够的内存。

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

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

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

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

3 个答案:

答案 0 :(得分:3)

原来这是由调用CreateThread而不是_beginthread引起的。备注部分中的Microsoft文档指出CreateThread causes conflicts when using the CRT library,实际上,一旦我们进行了更改,我们再也没有看到该错误。

答案 1 :(得分:1)

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

  

在Windows Vista中重写了隐式TLS处理[...]   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

  

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

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

底线:LoadLibrary是线程安全的。

答案 2 :(得分:0)

我发现这个过程是32位的。 在这种情况下,我使用命令

增加要处理的内存
  

bcdedit / set increaseuserva 3072