仅在使用std :: launch :: async policy

时间:2015-07-10 16:59:40

标签: c++ g++ std

以下代码在函数调用上产生段错误(后面是valgrind跟踪)。

GrooveFeat procGroove(double tRadius);

...

std::future<GrooveFeat> *features = new std::future<GrooveFeat>[evalCount];
for(unsigned int i = 0; i < evalCount; i++) {
  double effRadius = evalMin + evalStep*i;
  std::cout << "Allocating feature " << i << "\n";
  features[i] = std::async(std::launch::async, &procGroove, effRadius);
}

for(unsigned int i = 0; i < evalCount; i++) {
  std::cout << "Waiting on evaluation " << i << "/" << evalCount << "\n";
  GrooveFeat feat = features[i].get();

  ...
}
delete[] features;

当达到此代码时,我看到功能1-5的分配之间的段错误(确切的功能因执行而异)。如果手动将evalCount设置为1,则一旦激活线程,同样的错误就会持续存在。

Allocating feature 0
Allocating feature 1
Allocating feature 2
==27135== Thread 2:
==27135== Invalid read of size 8
==27135==    at 0x403B39: procGroove(double) (in profilParr)
==27135==    by 0x40552B: std::_Function_handler<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> (), std::__future_base::_Task_setter<std::unique_ptr<std::__future_base::_Result<GrooveFeat>, std::__future_base::_Result_base::_Deleter>, std::_Bind_simple<GrooveFeat (*(double))(double)>, GrooveFeat> >::_M_invoke(std::_Any_data const&) (in /profilParr)
==27135==    by 0x405608: std::__future_base::_State_baseV2::_M_do_set(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*) (in profilParr)
==27135==    by 0x4E43DCE: __pthread_once_slow (in /usr/lib/libpthread-2.21.so)
==27135==    by 0x405FEB: std::thread::_Impl<std::_Bind_simple<std::__future_base::_Async_state_impl<std::_Bind_simple<GrooveFeat (*(double))(double)>, GrooveFeat>::_Async_state_impl(std::_Bind_simple<GrooveFeat (*(double))(double)>&&)::{lambda()#1} ()> >::_M_run() (in profilParr)
==27135==    by 0x510C34F: execute_native_thread_routine (thread.cc:84)
==27135==    by 0x4E3D353: start_thread (in /usr/lib/libpthread-2.21.so)
==27135==    by 0x59D6BFC: clone (in /usr/lib/libc-2.21.so)
==27135==  Address 0xffffffffffffffc8 is not stack'd, malloc'd or (recently) free'd

因此,看起来segfault是由标准库引起的,因为执行在procGroove的任何部分实际执行之前结束。 编译命令是:

g++ -O3 -pthread -std=c++11 main.cpp -o profilParr -lpthread

一时兴起,我确认可执行文件具有相同的错误,无论优化级别如何(即使用-O0)。 知道怎么去调试这个吗?几年前似乎有关于类似问题的错误报告(https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54297),但它被标记为已解决(我正在使用v5.1.0)。

编辑:删除std :: launch :: async策略说明符允许程序无错误地执行。为什么??? 但是,看到它默认为延迟处理,它实际上失去了与并行执行procGroove()的任何相似性。有办法解决这个问题吗?

0 个答案:

没有答案