我的代码在调试模式下运行良好,但在发布模式下失败。
这是我失败的代码片段:
LOADER->AllocBundle(&m_InitialContent);
while(!m_InitialContent.isReady())
{
this->LoadingScreen();
}
AllocBundle(( 将加载包含在m_InitialContent中的内容,并在完成后将其就绪状态设置为 true。这是使用多线程实现的。
this->LoadingScreen()
应该呈现一个加载屏幕,但是目前尚未实现,因此该函数具有空体。
显然这可能是错误的原因:如果我给函数 LoadScreen(( 一行代码:std::cout<<"Loading"<<std::endl;
那么它会运行正常。
如果我不这样做,那么代码就会卡在while(!m_InitialContent.isReady())
它甚至永远不会跳转到括号(this->LoadingScreen();
(之间的代码。显然,它也不会更新 while 语句中的表达式,因为它永远卡在那里。
有没有人知道可能导致这种情况的原因是什么?如果是这样,问题可能是什么?我完全不解。
编辑:根据要求添加代码
内容加载器的成员:details::ContentBundleAllocator m_CBA;
void ContentLoader::AllocBundle(ContentBundle* pBundle)
{
ASSERT(!(m_CBA.isRunning()), "ContentBundleAllocator is still busy");
m_CBA.Alloc(pBundle, m_SystemInfo.dwNumberOfProcessors);
}
void details::ContentBundleAllocator::Alloc(ContentBundle* pCB, UINT numThreads)
{
m_bIsRunning = true;
m_pCB = pCB;
pCB->m_bIsReady = false;
m_NumRunningThrds = numThreads;
std::pair<UINT,HANDLE> p;
for (UINT i = 0; i < numThreads; ++i)
{
p.second = (HANDLE)_beginthreadex(NULL,
NULL,
&details::ContentBundleAllocator::AllocBundle,
this,
NULL,&p.first);
SetThreadPriority(p.second,THREAD_PRIORITY_HIGHEST);
m_Threads.Insert(p);
}
}
unsigned int __stdcall details::ContentBundleAllocator::AllocBundle(void* param)
{
//PREPARE
ContentBundleAllocator* pCBA = (ContentBundleAllocator*)param;
//LOAD STUFF [collapsed for visibility+]
//EXIT===========================================================================================================
pCBA->m_NumRunningThrds -= 1;
if (pCBA->m_NumRunningThrds == 0)
{
pCBA->m_bIsRunning = false;
pCBA->m_pCB->m_bIsReady = true;
pCBA->Clear();
#ifdef DEBUG
std::tcout << std::endl;
#endif
std::tcout<<_T("exiting allocation...")<<std::endl;
}
std::tcout<<_T("exiting thread...")<<std::endl;
return 0;
}
bool isReady() const {return m_bIsReady;}
当您在调试模式下编译代码时,编译器会在后台执行许多操作,以防止程序员犯的许多错误使应用程序崩溃。 当您在发布中运行时,所有投注都将关闭。 如果代码不正确,则在"发布"中比在"调试"中崩溃的可能性要大得多。
要检查的几件事:
- 确保所有变量都已正确初始化
- 确保没有任何死锁或争用条件
- 确保不会传递指向已释放的本地对象的指针
- 确保字符串正确以 NULL 结尾
- 不要
catch
您意想不到的异常,然后继续运行,就好像什么都没发生过一样。
您正在从不同的线程访问变量m_bIsReady
,而没有内存障碍。这是错误的,因为它可能由优化器或处理器缓存缓存。您必须保护此变量,防止与 CriticalSection 或互斥锁或库中可用的任何同步原语同时访问。
请注意,可能会有进一步的错误,但这个也绝对是一个错误。根据经验:从不同线程访问的每个变量都必须使用互斥锁/关键部分/任何东西进行保护。
快速浏览来看m_NumRunningThrds
似乎没有受到同时访问的保护,因此if (pCBA->m_NumRunningThrds == 0)
可能永远不会满意。