我有一个用于进行某些计算的类(多线程),并用Matlab的mex文件(在Linux中,用gcc 4.9编译)包装了它,即mex具有一个变量,该变量是该类的实例。为了监视计算,该类具有两个变量:_did_fit_finish( bool(boolean) ),因此我知道在计算结束时停止监视,而_info_str由另一个成员函数更新。这是监视功能的样子(g_info_print_interval是const全局):

template <typename T_Float>
void GmmFit<T_Float>::print_timing(void) {
    std::this_thread::sleep_for(std::chrono::milliseconds(200)); // let the gmm-fit start running
    while ( !_did_fit_finish ) {
        std::cout << _info_str.append("\n");
        std::this_thread::sleep_for(std::chrono::seconds(g_info_print_interval));
    }
}

问题是退出时,mex文件导致matlab崩溃,并显示以下消息:



崩溃发生在mex导出,因此我无法在mex代码中尝试捕获它。
一个问题是,何时抛出此类异常而不是失败的new运算符?我的代码没有尝试分配大量内存(至少在描述的用例中没有)

我到目前为止所知道的:
  • 它仅在“发布”模式下发生,也就是说,如果我使用mex -g进行编译,它将运行正常。因此,我无法使用gdb进行调试。
  • 它发生在特定的用例中:向mex函数的特定输入,并从使用mex文件的matlab脚本中的特定点调用mex-这真的很奇怪,因为如果我不使用而调用mex脚本(当然还有完全相同的输入),它不会崩溃。
  • 如果禁用监视(下面的MEX_GMM_VERBOSE),它不会崩溃。

  • 这是mex文件中的相关代码块:
     GmmFit<T_Float> gmmFit;
     std::thread readTiming;
     try {
         gmmFit.init(inMat.dimX, inMat.dimY, cfg, initType);
         #ifdef MEX_GMM_VERBOSE
         printf("number of available threads (as returned from std::thread::hardware_concurrency()): %d\n", gmmFit.num_available_threads);
         std::thread readTiming = std::thread(&GmmFit<T_Float>::print_timing, &gmmFit);
         #endif
         model = gmmFit.fit(inMat, initGuess);
         #ifdef MEX_GMM_VERBOSE
         readTiming.detach();
         #endif
      }
    catch (...) {
        readTiming.detach();
        mexErrMsgTxt("Unknown exception caught");
    }
    

    这是来自matlab崩溃消息的堆栈:
    Stack Trace (from fault):
    [  0] 0x00002aaaad1d4925                                   /lib64/libc.so.6+00207141 gsignal+00000053
    [  1] 0x00002aaaad1d6105                                   /lib64/libc.so.6+00213253 abort+00000373
    [  2] 0x00002aab417c7be5 /u/itamark/speech-magneton/research/utils/gmmFit/src/mex/mexGmmFit.mexa64+00457701
    [  3] 0x00002aab41780f26 /u/itamark/speech-magneton/research/utils/gmmFit/src/mex/mexGmmFit.mexa64+00167718
    [  4] 0x00002aab41780f71 /u/itamark/speech-magneton/research/utils/gmmFit/src/mex/mexGmmFit.mexa64+00167793
    [  5] 0x00002aab417b9900 /u/itamark/speech-magneton/research/utils/gmmFit/src/mex/mexGmmFit.mexa64+00399616
    [  6] 0x00002aaaacf8c9d1                             /lib64/libpthread.so.0+00031185
    [  7] 0x00002aaaad28ab6d                                   /lib64/libc.so.6+00953197 clone+00000109
    

    最佳答案

    您能否解释一下为什么使线程分离而不是加入?如果没有MEX_GMM_VERBOSE的定义,则根本不会创建线程,因此,问题在于线程可运行。
    mex退出后,相关对象被破坏,但是创建的计时线程可能仍在运行,并尝试访问/写入被破坏的对象(_info_str_did_fit_finish)。并且,由于诸如_info_str_did_fit_finish之类的引用变量也由其他线程更新,因此应使用锁对其进行保护。因此,我建议您加入定时线程,并用锁保护_info_str_did_fit_finish

    关于c++ - std::bad_alloc导致线程成员函数和mex文件崩溃,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26562504/

    10-12 16:06
    查看更多