线程成员函数和mex文件因std::bad_alloc而崩溃
thread member function and mex file crash with std::bad_alloc
我有一个用于进行一些计算的类(多线程),我用Matlab的mex文件(在Linux中,用gcc 4.9编译)将其封装,也就是说,mex有一个变量,它是该类的一个实例。为了监控计算,该类有两个变量:_did_fit_finish
(bool),所以我知道在计算结束时停止监控,_info_str
由另一个成员函数更新。这就是监视函数的样子(g_info_print_interval
是常量全局):
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崩溃,并显示以下消息:
抛出"std::bad_alloc"实例后调用terminate
崩溃发生在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()): %dn", 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
。
相关文章:
- 使用来自 Excel VBA 的 C++ dll 时"Bad DLL calling convention" - 如何解决?
- C++17 编解码器在将标准::字符串转换为标准::字符串时抛出"bad conversion"
- 对于代理容器上的迭代器来说,"least bad implementation"可能是什么?
- 组件对象模型 (COM):IMalloc::Alloc 在哪里分配内存?
- 获取错误:在抛出"std::bad::alloc"的实例后终止调用 what(): std::bad_alloc
- 为什么 GetSystemMetrics (SM_CXVIRTUALSCREEN) 返回'bad'值?
- 将 lambda 传递给 STL 集时出错"bad function call"
- 新的 C++14 位分隔符处"Bad Character" Eclipse Oxygen 错误
- 使用 #define 被认为是"bad practice"吗?
- "400 Bad request"使用 OpenSSL BIO 进行请求时
- CGAL:Hausdorff距离不良Alloc
- 解密文件AES_256_CBC返回"bad decrypt"错误
- 在C++流中,eof(),fail(),bad()和good()有什么区别
- C STD ::初始化类对象中的Alloc错误错误
- make / gcc:"bad build"的可能原因是什么?
- 什么是地址0xbaddc0dedeadbead "Bad decode dead bead"
- 在多线程环境中,什么可能导致"bad file descriptor"?
- 尝试解决HackerBank上的BFS挑战时出现错误的alloc异常
- "std::vector"在调整大小时引发"bad allocation"异常
- 尝试使用 execp、dup2 和管道实现 shell,挂起或"bad file descriptor"