簡體   English   中英

釋放模式錯誤,但不在調試模式下

[英]release mode error, but not in debug mode

我的代碼在調試模式下運行良好,但在發布模式下運行失敗。

這是我的代碼片段在失敗的地方:

LOADER->AllocBundle(&m_InitialContent);
while(!m_InitialContent.isReady())
{
    this->LoadingScreen();
}

AllocBundle()將加載m_InitialContent中包含的內容,並在完成后將其就緒狀態設置為true。 這是使用多線程實現的。

this->LoadingScreen()應該呈現一個加載屏幕,但是目前尚未實現,因此該函數的主體為空。

顯然這可能是導致錯誤的原因:如果我給函數LoadingScreen()一行代碼: std::cout<<"Loading"<<std::endl; 那么它將運行正常。

如果我不這樣做,則代碼將停留在while(!m_InitialContent.isReady())它甚至不會跳轉到括號之間的代碼( this->LoadingScreen(); )。 而且顯然它也不會更新while語句中的表達式,因為它永遠都停留在那里。

有誰知道這可能是什么原因? 如果是這樣,可能是什么問題? 我完全不解。


編輯:根據要求的其他代碼

ContentLoader的成員: 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;}

在“調試”模式下編譯代碼時,編譯器會在后台進行很多操作,以防止程序員犯下的許多錯誤導致應用程序崩潰。 當您在Release中運行時,所有投注均關閉。 如果您的代碼不正確,則在Release中崩潰的可能性要比在Debug中崩潰的可能性大。

需要檢查的幾件事:

  1. 確保正確設置了所有變量
  2. 確保您沒有任何僵局或競賽條件
  3. 確保您沒有傳遞指向已釋放的本地對象的指針
  4. 確保您的字符串正確以NULL結尾
  5. 不要catch您沒有想到的異常,然后繼續運行,就好像什么都沒發生一樣。

您正在從沒有內存障礙的其他線程訪問變量m_bIsReady 這是錯誤的,因為它可能被優化器或處理器緩存所緩存。 您必須使用CriticalSection,互斥量或庫中可用的任何同步原語來保護此變量,以防止同時訪問該變量。

請注意,可能還會有其他錯誤,但這絕對也是一個錯誤。 根據經驗:從不同線程訪問的每個變量都必須使用互斥/關鍵部分/任何內容進行保護。

快速m_NumRunningThrds似乎並不能防止同時訪問,因此if (pCBA->m_NumRunningThrds == 0)可能永遠無法滿足。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM