该问题涉及大量代码,因此我希望尝试仅给出一些示例代码的运行情况的想法。如果有我似乎遗漏的内容,请发表评论,我会添加更多内容。无论如何,我有一个使用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::vectorsresize替换mxCalloc调用,但是我想先了解最新情况,然后再更改一堆代码。

更新
我只是检查了一下代码,并使用了带有resize的 vector 来代替mxCallocmxFree,这解决了我遇到的所有问题。仅供以后参考,绝对不要在任何并行区域使用MEX API。即使您使用critical节,它仍然会导致我的linux系统崩溃。这个问题实际上被掩盖了一段时间,因为使用Windows 7的笔记本电脑上没有发生此问题。

最佳答案

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



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

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

10-05 17:39