我想一個程序編號異步/期貨:在C++ 11
#include <iostream>
#include <thread>
#include <future>
int foo() {
return 0;
}
int main(int argc, char* argv[]) {
for (auto i = 0L; i < 10000; ++i) {
auto f = std::async(foo);
f.get();
}
return 0;
}
編譯VS11 64。
體形:
cl /EHsc /Zi async.cpp && async
對於我這個程序崩潰。我懷疑,同時實際運行的期貨數量是有限的。如果我將迭代次數減少到幾個訂單,它就可以工作。
於是,兩個問題:
是否有實際運行期貨在C++ 11的限制?
爲什麼此代碼會崩潰?如果我明確地在「async()」之後立即執行「get()」,它必須在下一次迭代之前完成未來,這意味着一次只能運行一個未來。
UPDATE
我已經簡化了代碼:
#include <future>
int main(int argc, char* argv[]) {
for (auto i = 0L; i < 1000000; ++i) {
auto f = std::async([](){ return 0; });
f.get();
}
return 0;
}
它仍然崩潰了我。它不扔,我檢查了。但現在我有一個可見的堆棧跟蹤:
async.exe!_Mtx_unlock(_Mtx_internal_imp_t * * mtx) Line 229 C++
async.exe!std::_Mtx_unlockX(_Mtx_internal_imp_t * * _Mtx) Line 84 C++
async.exe!std::_Mutex_base::unlock() Line 47 C++
async.exe!std::unique_lock<std::mutex>::~unique_lock<std::mutex>() Line 284 C++
async.exe!std::_Associated_state<int>::_Set_value(int && _Val, bool _At_thread_exit) Line 358 C++
async.exe!std::_Packaged_state<int __cdecl(void)>::_Call_immediate() Line 569 C++
async.exe!std::_Async_state<int>::`std::U_Nil::ain::ain'::`3'::<lambda_A200A86DFF9A63A1>::operator()() Line 700 C++
[email protected]@[email protected]<lambda_A200A86DFF9A63A1>@[email protected][email protected]<lambda_23AC5A2FBB53FD4D>@[email protected][email protected]@@[email protected]@[email protected]@[email protected]@@[email protected]@@[email protected]@[email protected]@[email protected][email protected][email protected]<lambda_23AC5A2FBB53FD4D>@[email protected][email protected]@@[email protected]@[email protected]@[email protected]@@[email protected]@[email protected][email protected]@[email protected]@QEAAXXZ() Line 420 C++
[email protected][email protected][email protected]<lambda_A200A86DFF9A63A1>@[email protected][email protected]<lambda_23AC5A2FBB53FD4D>@[email protected][email protected]@@[email protected]@[email protected]@[email protected]@@[email protected]@@[email protected]@[email protected]@[email protected][email protected][email protected]<lambda_23AC5A2FBB53FD4D>@[email protected][email protected]@@[email protected]@[email protected]@[email protected]@@[email protected]@[email protected][email protected]@[email protected]@[email protected][email protected][email protected]@@[email protected]@[email protected]@[email protected]@@[email protected]@@[email protected][email protected]@[email protected]@[email protected]@[email protected]@@[email protected]@UEAAXXZ() Line 217 C++
async.exe!std::_Func_class<void,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil>::operator()() Line 486 C++
async.exe!`Concurrency::details::_MakeVoidToUnitFunc'::`3'::<lambda_25D33530A43E1C90>::operator()() Line 1056 C++
async.exe!std::_Callable_obj<`Concurrency::details::_MakeVoidToUnitFunc'::`3'::<lambda_25D33530A43E1C90>,0>::_ApplyX<Concurrency::details::_Unit_type>() Line 420 C++
async.exe!std::_Func_impl<std::_Callable_obj<`Concurrency::details::_MakeVoidToUnitFunc'::`3'::<lambda_25D33530A43E1C90>,0>,std::allocator<std::_Func_class<Concurrency::details::_Unit_type,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil> >,Concurrency::details::_Unit_type,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil>::_Do_call() Line 217 C++
async.exe!std::_Func_class<Concurrency::details::_Unit_type,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil>::operator()() Line 486 C++
async.exe!`Concurrency::details::_Task_impl<Concurrency::details::_Unit_type>::_ScheduleTask'::`3'::<lambda_7D9BCD859405C05B>::operator()() Line 325 C++
async.exe!Concurrency::details::_PPLTaskHandle<`Concurrency::details::_Task_impl<Concurrency::details::_Unit_type>::_ScheduleTask'::`3'::<lambda_7D9BCD859405C05B> >::operator()() Line 72 C++
async.exe!Concurrency::details::_UnrealizedChore::_InvokeBridge<Concurrency::details::_PPLTaskHandle<`Concurrency::details::_Task_impl<Concurrency::details::_Unit_type>::_ScheduleTask'::`3'::<lambda_7D9BCD859405C05B> > >(Concurrency::details::_PPLTaskHandle<`Concurrency::details::_Task_impl<Concurrency::details::_Unit_type>::_ScheduleTask'::`3'::<lambda_7D9BCD859405C05B> > * _PChore) Line 4190 C++
async.exe!Concurrency::details::_UnrealizedChore::_UnstructuredChoreWrapper(Concurrency::details::_UnrealizedChore * pChore) Line 275 C++
async.exe!Concurrency::details::_PPLTaskChore::_DeletingChoreWrapper(Concurrency::details::_UnrealizedChore * pChore) Line 78 C++
async.exe!Concurrency::details::InternalContextBase::ExecuteChoreInline(Concurrency::details::WorkItem * pWork) Line 1600 C++
async.exe!Concurrency::details::InternalContextBase::Dispatch(Concurrency::DispatchState * pDispatchState) Line 1704 C++
async.exe!Concurrency::details::FreeThreadProxy::Dispatch() Line 191 C++
async.exe!Concurrency::details::ThreadProxy::ThreadProxyMain(void * lpParameter) Line 173 C++
kernel32.dll!0000000076df652d() Unknown
ntdll.dll!0000000076f2c521() Unknown
和線程:
Unflagged 1864 0 Worker Thread ntdll.dll thread ntdll.dll!0000000076f518ca Normal
Unflagged 10964 0 Main Thread Main Thread async.exe!do_signal Normal
Unflagged 7436 0 Worker Thread ntdll.dll thread ntdll.dll!0000000076f52c1a Normal
Unflagged 10232 0 Worker Thread async.exe!Concurrency::details::ThreadProxy::ThreadProxyMain async.exe!Concurrency::details::ThreadProxy::SuspendExecution Normal
Unflagged > 10624 0 Worker Thread async.exe!Concurrency::details::ThreadProxy::ThreadProxyMain async.exe!_Mtx_unlock Normal
Unflagged 4756 0 Worker Thread async.exe!Concurrency::details::ThreadProxy::ThreadProxyMain async.exe!Concurrency::details::ThreadProxy::SuspendExecution Normal
Unflagged 11100 0 Worker Thread async.exe!Concurrency::details::ThreadProxy::ThreadProxyMain async.exe!Concurrency::details::InternalContextBase::WaitForWork Normal
Unflagged 6440 0 Worker Thread async.exe!Concurrency::details::ThreadProxy::ThreadProxyMain async.exe!std::vector<std::pair<void (__cdecl*)(void * __ptr64),void * __ptr64>,std::allocator<std::pair<void (__cdecl*)(void * __ptr64),void * __ptr64> > >::_Tidy Normal
我使用VS 11.0.40825.2 PREREL。
聽起來像一個編譯器錯誤。 – 2012-04-24 15:56:17
我不相信這個調用會啓動另一個線程,它只是一個延遲執行。例如,foo應該在執行f.get()行時被調用。 – alanxz 2012-04-24 16:02:08
調試器應該可以幫助您理解代碼崩潰的原因。我會在假設編譯器被破壞之前嘗試。 – 2012-04-24 16:03:10