c++ - MxCalloc 和 MxFree 与 OpenMP 结果双重释放或损坏

标签 c++ c matlab openmp mex

该问题涉及大量代码,因此我将尝试通过一些示例代码来大致了解发生了什么。如果有什么我似乎遗漏的,请发表评论,我会添加更多。无论如何,我有一个对象,其方法使用 openMP:

#pragma omp parallel 
{  
int num_thread = omp_get_thread_num(); 

// This function will allocate and deallocate memory through Mxcalloc and MxFree before returning
foo.get_foo(num_thread);
}   

foo类已在另一个文件中定义(该文件是使用 -C 标志编译的)并且已编译并链接到使用 openMP 的对象。它使用两种方法分配和释放内存:

void foo::alloc(const int &h, const int &w) {
if (value == NULL) {
        width = w;
        height = h;
        value = (double *)mxCalloc(h*w,sizeof(double));
    } else {
        mexPrintf("Memory has already been allocated when attempting to alloc.\n");
    }
}


void foo::free() {
    if (value != NULL) {
        width = 0;
        height = 0;
        mxFree(value);
        value = NULL;
    } else {
        mexPrintf("Memory has not been allocated yet when attempting to free.\n");  
    }
}

代码在单线程中运行得非常好。但是,当使用多线程运行时,出现以下错误:

*** glibc detected *** /usr/local/MATLAB/R2013a/bin/glnxa64/MATLAB: double free or     corruption (out): 0x00007f4118019d20 ***
*** glibc detected *** /usr/local/MATLAB/R2013a/bin/glnxa64/MATLAB: malloc(): memory corruption: 0x00007f4101120541 ***
*** glibc detected *** /usr/local/MATLAB/R2013a/bin/glnxa64/MATLAB: double free or corruption (out): 0x00007f412c011260 ***
*** glibc detected *** /usr/local/MATLAB/R2013a/bin/glnxa64/MATLAB: malloc(): memory corruption: 0x00007f4101120541 ***

现在,如果我删除所有 free调用(随后删除所有 mxFree 调用),并重新编译/重新运行代码,它似乎工作正常(我觉得这很奇怪,因为对 mxFree 的调用仅在指针不为空时才会发生 - 所以我不知道问题是什么)。所以我将范围缩小到 mxFree调用不是线程安全的。

我还尝试添加一个 critical部分如下所示:

#pragma omp parallel 
{                  
int num_thread = omp_get_thread_num();

// This function will allocate and deallocate memory through Mxcalloc and MxFree before returning
#pragma omp critical
{
    foo.get_foo(num_thread);
}
}   

并且代码仍然无法正常工作并导致类似的错误消息。所以我的问题是:是 mxFreemxCalloc完全非线程安全——因为它们只在被单个线程调用时工作,即使被其他线程独立调用(由 critical 部分保证),函数仍然会失败?我将不胜感激任何提示或建议。我在考虑也许只用 std::vectors 替换 mxCalloc 调用和 resize但我想知道在更改一堆代码之前先发生了什么。

更新 我刚刚浏览了我的代码并将 vector 与 resize 一起使用代替 mxCallocmxFree这解决了我遇到的所有问题。仅供将来引用,绝对避免在任何并行区域中使用 MEX API。即使你使用 critical部分,它仍然会导致我的 linux 系统崩溃。这个问题实际上被掩盖了一段时间,因为这个问题没有发生在我使用 Windows 7 的笔记本电脑上。

最佳答案

C MEX API is not thread-safe .根据 MathWorks 支持团队的说法:

Since the MEX API is not thread safe, no MEX API functions can be used in the spawned threads...

但是,似乎一些 MEX API 函数have been made thread-safe ,例如 mexErrMsgIdAndTxt。看来动态内存分配还在黑名单上。

代替 mxMallocmxCalloc,使用 malloccalloc(或 newdelete[])。

关于c++ - MxCalloc 和 MxFree 与 OpenMP 结果双重释放或损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24085098/

相关文章:

带有输出的 C++ mex 文件错误

c++ - 在 C++ 中查找带零的整数的长度?

C 代码未定义行为 - 在 func 中重新分配结构

android - 在平面图图像上显示路线

matlab - 如何通过降低特征维数来改进LBP算子

C++ Win32 多行静态标签

c++ - 无法使用数组获得正确的值

c - 我应该使用什么方法来知道在进程 fork 然后执行后打开了哪些 fds

我可以将多个有序语句放入一个有序 for 循环 (OpenMP) 中吗?

matlab - 如何从 matlab 中的元胞数组写入多个 .csv 文件