简单代码(下面,在100个线程中运行malloc()/ free()序列)在我试图运行的任何Windows操作系统上崩溃。
非常感谢任何帮助。
也许使用某些编译器的指令可以帮忙吗?
我们在Release / x64中在VS2017中构建exe;可执行文件在运行几分钟后尝试的任何Windows平台上崩溃。
我尝试使用VS2015构建,但它没有帮助。
Linux上的相同代码运行良好。
实际上,问题比看起来更严重;我们遇到的情况是,我们的服务器代码在生产环境中每天多次崩溃而没有任何理由(当用户调用的数量超过某个值时)。我们试图确定下来 问题并创建了最简单的解决方案来重现问题。
存档VS项目是here。
VS说命令行是:
/Yu"stdafx.h" /GS /GL /W3 /Gy /Zc:wchar_t /Zi /Gm- /O2 /sdl
/Fd"x64\Release\vc140.pdb" /Zc:inline /fp:precise /D "NDEBUG"
/D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /errorReport:prompt /WX- /Zc:forScope /Gd
/Oi /MD /Fa"x64\Release\" /EHsc /nologo /Fo"x64\Release\" /Fp"x64\Release\MallocTest.pch"
代码:
#include "stdafx.h"
#include <iostream>
#include <thread>
#include <conio.h>
using namespace std;
#define MAX_THREADS 100
void task(void)
{
while (true)
{
char *buffer;
buffer = (char *)malloc(4096);
if (buffer == NULL)
{
cout << "malloc error" << endl;
}
free(buffer);
}
}
int main(int argc, char** argv)
{
thread some_threads[MAX_THREADS];
for (int i = 0; i < MAX_THREADS; i++)
{
some_threads[i] = thread(task);
}
for (int i = 0; i < MAX_THREADS; i++)
{
some_threads[i].join();
}
_getch();
return 0;
}
答案 0 :(得分:1)
在您非常小的MVCE中,没有任何内容表示编程错误,malloc()
和free()
应该是线程安全的,在cout
上调用的方法也应该是线程安全的。该程序并非旨在永远停止,因此它似乎是在多线程上下文中对malloc()
进行的精细压力测试。
但是请注意,如果malloc()
失败,尝试将错误报告给cout
是可疑的,这可能会进一步调用malloc()
进行缓冲。建议将错误报告给cerr
或使cout
无缓冲。无论如何,malloc()
失败都不会导致崩溃,即使在流方法中也是如此。
似乎您在VS目标平台上链接到的运行时库中发现了一个错误。跟踪崩溃之前程序的内存使用情况将很有趣。内存使用率的稳定增长也将表明运行时库中存在一些问题。该程序永远不会一次分配超过MAX_THREADS
个4K块,因此内存使用应保持非常低的水平,低于2MB,包括与malloc()
的现代实现所使用的基于线程的缓存相关的开销。