2

我制作了这个简单的测试程序,它有时会触发 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=0x0argflist =0x7d92f7c4) 第 502 行 C msvcr100d.dll!_CrtDbgReportWV(int nRptType=2, const wchar_t * szFile=0x0f45d230, int nLine=728, const wchar_t * szModule=0x00000000, const wchar_t * szFormat=0x0f45dx709 格式=7 * charlist) 241 + 0x1d 字节 C++ msvcr100d.dll!_CrtDbgReportW(int nRptType=2, const wchar_t * szFile=0x0f45d230, int nLine=728, const wchar_t * szModule=0x00000000, const wchar_t * szFormat=0x0f45d401d, ...) 第 258 行字节 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,匿名命名空间'::,0>::_Invoke(const int & _First=0, unsigned int & _Index=1418, constanonymous-namespace'::<lambda0> & _Func={...}) Line 1445 C++ Lockable.exe!Concurrency::_Parallel_chunk_helper<int,unsigned int,匿名命名空间'::,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++

可锁定的.exe!anonymous namespace'::<lambda0>::operator()(int i=4177) Line 16 C++ Lockable.exe!Concurrency::_Parallel_chunk_helper_invoke<int,unsigned int,匿名命名空间'::,0>::_Invoke(const int & _First=0, unsigned int & _Index=4177, constanonymous-namespace'::<lambda0> & _Func={...}) Line 1445 C++ Lockable.exe!Concurrency::_Parallel_chunk_helper<int,unsigned int,匿名命名空间'::,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 在生产环境中使用有问题吗?

感谢您的任何投入!

4

2 回答 2

4

因此,最后,在 Microsoft Connect(或社交?)上发布问题后,该问题已得到彻底解释。

http://social.msdn.microsoft.com/Forums/en-US/parallelcppnative/thread/9601a2d0-b1ef-4d81-8743-73c3965a7b63

http://social.msdn.microsoft.com/Forums/eu/parallelcppnative/thread/38d2e8c8-e863-4da0-a45a-9776ab27feed

于 2013-01-28T15:46:37.953 回答
0

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

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

于 2013-01-24T03:04:10.907 回答