我有一个用于进行某些计算的类(多线程),并用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_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/