我的静态链接Visual C ++ 2012程序偶尔会生成CRTL错误:“R6016 - 没有足够的空间用于线程数据”。
Microsoft提供的最小文档说明在生成新线程时会生成此错误消息,但是没有为其分配足够的内存。
但是,我的代码只在几个明确定义的情况下显式生成了一个新线程,这两个都没有在这里发生(尽管Microsoft库内部确实产生了很好的线程)。当程序刚刚存在于后台时,一个用户报告了此问题。
不确定它是否相关,但我没有覆盖默认的1MB保留堆栈大小或堆大小,并且我的程序使用的总内存通常非常小(在具有12GB实际RAM的系统上为3MB-10MB,其中一半以上是未分配的。)
这很少发生(所以我无法追踪它),并且已在多台机器上报告。我在Windows 8.1上只听说过这个,但我不会读太多内容。
是否有某些编译器设置可能会影响此错误?还是编程错误?
答案 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;
}
}
当程序启动时,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