我有一个用std :: async调用的函数,有时会抛出异常,有时却不会抛出异常。我无法真正掌握这个错误,所以我希望有人可以指出我正确的方向。
它有很多代码,所以我将尝试总结一下我认为的基本部分。我得到的错误就是这个
Dodgson.exe中0x77EC897E(ntdll.dll)的未处理异常: 0xC000000D:将无效参数传递给服务或函数。
Base.h
class Base {
public:
void threadControl(int maxThreads);
virtual void threadCode(Data n) = 0;
private:
vector<future<void>> m_futures;
mutex m_mutex;
atomic<int> m_minimum;
vector<Data> m_winData; // as this is shared data, i would like to make it atomic or volatile, but that won't work. Having a mutex must suffice.
}
Base.cpp
void Base::threadControl(int maxThreads) {
vector<Data> queue = Somewhere::readData();
while( !queue.empty() ) {
if( m_futures.size() < maxThreads ) {
m_futures.push_back(std::async(std::launch::async, &Base::threadCode, this, queue.back())); // this works properly
queue.pop_back();
} else {
// I think this might be a critical part. This code tries to look for finished threads and deletes them from the thread-holder m_futures
for( unsigned int i=0; i<m_futures.size(); i++ ) {
if( m_futures[i].wait_for(chrono::milliseconds(10))==std::future_status::ready ) {
m_futures.erase(m_futures.begin()+i);
i--;
}
}
}
}
// waiting for all still running threads to finish
for( unsigned int i=0; i<m_futures.size(); i++ ) {
m_futures[i].get();
}
}
Impl.h
class Impl : public Base {
virtual void threadCode(Data n);
}
Impl.cpp
void Impl::threadCode(Data n) {
while( !n.empty() ) {
// .. work on next data block, get a "local minimum value" for it. Compare it with "global minimum value" m_minimum, which all threads can manipulate. This should be a critical stage too.
int localMinimum = Somewhere::getMinimum(n.current());
m_mutex.lock();
if( m_minimum > localMinimum ) {
m_minimum = localMinimum;
m_winData.push_back(n.current());
}
m_mutex.unlock();
n.pop();
}
}
我希望我没有用代码过度。但是,如果不清楚我很乐意提供更多信息。
VS2010 callstack没有任何我能理解的内容,只需快速查看~50个电话中的最后10个:
ntdll.dll!77e52289()未知[下面的框架可能不正确和/或 缺少,没有为ntdll.dll加载的符号]
ntdll.dll!77ec87a7()未知msvcr110d.dll!__ crtSetThreadpoolTimer(_TP_TIMER * pti,_FILETIME * pftDueTime,unsigned long msPeriod,unsigned long msWindowLength)Line 521 C msvcr110d.dll!__ crtWaitForThreadpoolTimerCallbacks(_TP_TIMER * pti,int fCancelPendingCallbacks)第539 C行 msvcr110d.dll!并发::细节:: EventWaitNode ::手托(并发::上下文 * * pContextOut)第330行C ++ msvcr110d.dll!并发:: details :: _ Condition_variable :: notify_all() 第688行C ++ msvcp110d.dll!do_signal(_Cnd_internal_imp_t * * cond, int all)第65行C ++ msvcp110d.dll!_Cnd_broadcast(_Cnd_internal_imp_t * * cond)行 88 C ++ My_Program.exe!std :: _ Cnd_broadcastX(_Cnd_internal_imp_t * * _Cnd)第103行C ++ My_Program.exe!std :: condition_variable :: notify_all()第55行C ++ My_Program.exe!的std :: _ Associated_state :: _ Do_notify(STD :: unique_lock * _Lock,bool _At_thread_exit)第549行C ++
......还有更多
最后但并非最不重要的是,这很可能是一个时间问题。在调试时,我在一个实现中填充了许多行,例如“cout&lt;&lt;”2“&lt;&lt; endl;”为了缩小bug的位置。
这导致很少发生错误的实现。虽然它在运行其代码约3秒后通常会崩溃,但现在大部分时间运行约5分钟并正常终止。没有评论的所有其他实现在~3秒后仍会遇到错误。所以我想通过每秒向控制台打印~100行文本来“解决”问题,从而减慢程序速度。
..我不想像这样修复我的代码。