【问题标题】:PPL critical_section/parallel_for crashing under visual studio 2010?PPL critical_section/parallel_for 在 Visual Studio 2010 下崩溃?
【发布时间】:2013-01-07 13:14:44
【问题描述】:

我制作了这个简单的测试程序,它有时会触发 Debug Break 或者它只是崩溃(在 Debug/Win32/VS2010SP1 下) - 当然,有时它甚至可以工作。我做错了什么还是PPL(VS2010)中的某个地方有错误?

#include "stdafx.h"
#include <ppl.h>
#include <vector>

int _tmain(int argc, _TCHAR* argv[])
{
    std::vector<int> vi;
    Concurrency::critical_section cs;
    Concurrency::parallel_for(0, 10000, [&](int i)
    {
        Concurrency::critical_section::scoped_lock l(cs);
        vi.push_back(i);
    });
    return 0;
}

Debug Break 调用堆栈如下所示:

msvcr100d.dll!_CrtDbgBreak() 第 85 行 C msvcr100d.dll!_VCrtDbgReportW(int nRptType=2, const wchar_t * szFile=0x0f45d230, int nLine=728, const wchar_t * szModule=0x00000000, const wchar_t * szFormat=0x0f45d400, char * arglist=0x7d92f7c4) 行 msvcr100d.dll!_CrtDbgReportWV(int nRptType=2, const wchar_t * szFile=0x0f45d230, int nLine=728, const wchar_t * szModule=0x00000000, const wchar_t * szFormat=0x0f45d400, char * arglist=0x7d9+02f7c4 行 C++) msvcr100d.dll!_CrtDbgReportW(int nRptType=2, const wchar_t * szFile=0x0f45d230, int nLine=728, const wchar_t * szModule=0x00000000, const wchar_t * szFormat=0x0f45d400, ...) Line 258 + 0x1d bytes C++ msvcr100d.dll!Concurrency::details::LockQueueNode::Copy(Concurrency::details::LockQueueNode * pCopyFromNode=0x7d92f908) 第 728 行 + 0x27 字节 C++ msvcr100d.dll!Concurrency::critical_section::_Acquire_lock(void * _PLockingNode=0x7d92f908, bool _FHasExternalNode=true) 第 1019 行 C++ msvcr100d.dll!Concurrency::critical_section::scoped_lock::scoped_lock(Concurrency::critical_section & _Critical_section=locked) 第 1083 行 C++ Lockable.exe!anonymous namespace'::<lambda0>::operator()(int i=1418) Line 14 + 0x11 bytes C++ Lockable.exe!Concurrency::_Parallel_chunk_helper_invoke<int,unsigned int,anonymous namespace'::,0>::_Invoke(const int & _First=0, unsigned int & _Index=1418, const anonymous-namespace'::<lambda0> & _Func={...}) Line 1445 C++ Lockable.exe!Concurrency::_Parallel_chunk_helper<int,unsigned int,anonymous namespace'::,0>::operator() () 第 1781 行 + 0x16 字节 C++ Lockable.exe!Concurrency::task_handle,0> > >(Concurrency::task_handle,0> > * _PChore=0x7c13fba8 {_M_first=0 _M_step=1 _M_function={...} ...}) 第 3495 行 C++ msvcr100d.dll!Concurrency::details::_UnrealizedChore::_StructuredChoreWrapper(Concurrency::details::_UnrealizedChore * pChore=0x7c13fba8 {_M_first=0 _M_step=1 _M_function={...} ...}) 第 99 行 + 0xc 字节C++ msvcr100d.dll!Concurrency::details::_UnrealizedChore::_Invoke() 第 3454 行 + 0xc 字节 C++ msvcr100d.dll!Concurrency::details::WorkItem::Invoke() 第 75 行 C++ msvcr100d.dll!Concurrency::details::InternalContextBase::ExecuteChoreInline(Concurrency::details::WorkItem * pWork=0x7d92fe7c) 第 1385 行 C++ msvcr100d.dll!Concurrency::details::InternalContextBase::Dispatch(Concurrency::DispatchState * pDispatchState=0x7d92fe9c) 第 1478 行 C++ msvcr100d.dll!Concurrency::details::FreeThreadProxy::Dispatch() 第 157 行 C++ msvcr100d.dll!Concurrency::details::ThreadProxy::ThreadProxyMain(void * lpParameter=0x2ed5b4f0) 第 162 行 C++ kernel32.dll!763c33aa()
[以下帧可能不正确和/或丢失,没有为 kernel32.dll 加载符号]
ntdll.dll!771a9ef2()
ntdll.dll!771a9ec5()

我刚刚遇到的一次崩溃看起来好像没有锁住(cs: not_locked)

Lockable.exe!std::vector >::_Orphan_range(int * _First=0x0000c5db, int * _Last=0x0000c5db) 第 1442 行 + 0x5 字节 C++ Lockable.exe!std::vector >::push_back(const int & _Val=4177) 第 995 行 C++

Lockable.exe!anonymous namespace'::<lambda0>::operator()(int i=4177) Line 16 C++ Lockable.exe!Concurrency::_Parallel_chunk_helper_invoke<int,unsigned int,anonymous namespace'::,0>::_Invoke(const int & _First=0, unsigned int & _Index=4177, const anonymous-namespace'::<lambda0> & _Func={...}) Line 1445 C++ Lockable.exe!Concurrency::_Parallel_chunk_helper<int,unsigned int,anonymous namespace'::,0>:: operator()() 第 1833 行 + 0x16 字节 C++ Lockable.exe!Concurrency::task_handle,0> > >(Concurrency::task_handle,0> > * _PChore=0x7cbffc24 {_M_first=0 _M_step=1 _M_function={...} ...}) 第 3495 行 C++ msvcr100d.dll!Concurrency::details::_UnrealizedChore::_StructuredChoreWrapper(Concurrency::details::_UnrealizedChore * pChore=0x7cbffc24 {_M_first=0 _M_step=1 _M_function={...} ...}) 第 99 行 + 0xc 字节C++ msvcr100d.dll!Concurrency::details::_UnrealizedChore::_Invoke() 第 3454 行 + 0xc 字节 C++ msvcr100d.dll!Concurrency::details::WorkItem::Invoke() 第 75 行 C++ msvcr100d.dll!Concurrency::details::InternalContextBase::ExecuteChoreInline(Concurrency::details::WorkItem * pWork=0x7bc0fab4) 第 1385 行 C++ msvcr100d.dll!Concurrency::details::InternalContextBase::Dispatch(Concurrency::DispatchState * pDispatchState=0x7bc0fad4) 第 1478 行 C++ msvcr100d.dll!Concurrency::details::FreeThreadProxy::Dispatch() 第 157 行 C++ msvcr100d.dll!Concurrency::details::ThreadProxy::ThreadProxyMain(void * lpParameter=0x2dcf6200) 第 162 行 C++ kernel32.dll!763c33aa()
[以下帧可能不正确和/或丢失,没有为 kernel32.dll 加载符号]
ntdll.dll!771a9ef2()
ntdll.dll!771a9ec5()

即使在 PPL 内部实现中也可能存在其他随机访问违规,我想您可以重现这些违规行为。 (希望)

我在 Visual Studio 2012 Express for Desktop 下运行了相同的程序,经过多次测试后一切似乎都正常运行。

我想知道VS2010下的PPL在生产环境中使用是否有问题?

感谢您的任何意见!

【问题讨论】:

  • 代码看起来不错,并且使用 VC++ 2012 RTM 对我来说运行良好。你可以尝试在MS Connect 上报告一个错误(如果那里还没有),但如果它是在 VC++ 2012 中修复的问题,我怀疑他们现在会在 VC++ 2010 中修复它。跨度>

标签: c++ visual-studio-2010 visual-c++ c++11 ppl


【解决方案1】:

在我看来,您应该在程序结束时等待。例程parallel_for 为并发执行创建了线程,并将自行运行。但是,main 正在退出,这将导致所有正在运行的线程停止(或使它们无效)。

尝试进行一些阻塞调用(就像用户输入一样简单),看看它是否有效。

【讨论】:

  • 据我所知,parallel_for[_each] 专门设计用于在算法结束时加入所有并行任务。一个简单的验证是在main末尾的return语句处放一个断点,它在到达断点之前就崩溃了。此外,PPL 根本没有提供这样一个显式的阻塞功能,这肯定违反了它的设计目标——让事情以最少的 [b] 锁定(使用同步对象)并行执行!
  • 确实如此!我错过了parellel_for 本身会等待执行的事实。与异步执行的任务混合在一起。
【解决方案2】:
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-25
  • 1970-01-01
  • 2012-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多