gpt4 book ai didi

c++ - 线程成员函数和 mex 文件因 std::bad_alloc 而崩溃

转载 作者:行者123 更新时间:2023-11-30 03:59:59 25 4
gpt4 key购买 nike

我有一个用于进行一些计算(多线程)的类,我用 Matlab 的 mex 文件(在 Linux 中,用 gcc 4.9 编译)包装它,也就是说,mex 有一个变量,它是该类的一个实例.为了监控计算,该类有两个变量:_did_fit_finish (bool),所以我知道在计算结束时停止监控,以及由另一个更新的_info_str成员函数。这是监控函数的样子(g_info_print_interval 是一个 const global):

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 崩溃并显示以下消息:

terminate called after throwing an instance of 'std::bad_alloc'

崩溃发生在 mex 导出,所以我不能在 mex 代码中 try catch 它。一个问题是,除了失败的 new 运算符之外,何时会抛出此类异常?我的代码不会尝试分配大量内存(至少在描述的用例中不会)

目前我所知道的:

  1. 它只发生在“发布”模式下,也就是说,如果我用 mex -g 编译它运行正常。所以我无法使用 gdb 进行调试。
  2. 它发生在一个特定的用例中:对 mex 函数的特定输入,并从 使用 mex 文件的 matlab 脚本中的特定点调用 mex - 这真的很奇怪,因为如果我只是调用 mex 而不使用脚本(当然还有完全相同的输入),它不会崩溃。
    1. 如果我禁用监控(下面的 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++ - 线程成员函数和 mex 文件因 std::bad_alloc 而崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26562504/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com