2013-02-17 52 views
0

我的函數做的是循環遍歷一個布爾數組,並且在找到一個設置爲false的元素時,它被設置爲true。該函數是我的內存管理器singleton類中的一個方法,它返回一個指向內存的指針。我得到一個錯誤,我的迭代器似乎循環並最終從頭開始,我相信這是因爲多個線程正在調用該函數。多線程環境中函數的錯誤

void* CNetworkMemoryManager::GetMemory() 
{ 
     WaitForSingleObject(hMutexCounter, INFINITE); 

    if(mCounter >= NetConsts::kNumMemorySlots) 
    { 
     mCounter = 0; 
    } 

    unsigned int tempCounter = mCounter; 

    unsigned int start = tempCounter; 

    while(mUsedSlots[tempCounter]) 
    { 
     tempCounter++; 

     if(tempCounter >= NetConsts::kNumMemorySlots) 
     { 
      tempCounter = 0; 
     } 

     //looped all the way around 
     if(tempCounter == start) 
     { 
      assert(false); 
      return NULL; 
     } 
    } 

    //return pointer to free space and increment 

    mCounter = tempCounter + 1; 
     ReleaseMutex(hMutexCounter); 

    mUsedSlots[tempCounter] = true; 
    return mPointers[tempCounter]; 
} 

我的錯誤是斷言在循環中關閉。我的問題是我如何修復這個函數,並且是多線程引起的錯誤?

編輯:添加一個互斥鎖來保護mCounter變量。不用找了。錯誤仍然發生。

+0

這是什麼問題? – juanchopanza 2013-02-17 20:07:58

+0

所以基本上你問是否多線程/併發可能是此功能不能正常工作的原因? – LihO 2013-02-17 20:14:15

+0

是的,我想知道如果這是原因,我該如何修復函數 – user998797 2013-02-17 20:17:45

回答

1

我不能說如果錯誤是由多線程或不,但我可以說你的代碼是不是線程安全的。

,釋放與

ReleaseMutex(hMutexCounter); 

鎖,然後訪問tempCounter和mUsedSlots:

mUsedSlots[tempCounter] = true; 
return mPointers[tempCounter]; 

這兩者都不是常量。這是數據競爭,因爲您沒有正確序列化訪問這些變量。

更改爲:

mUsedSlots[tempCounter] = true; 
const unsigned int retVal = mPointers[tempCounter]; 
ReleaseMutex(hMutexCounter); 
return retVal; 

那麼至少你的代碼是線程安全的,這是否解決您的問題,我不能說,嘗試一下。在具有多個內核的機器上,由於數據競爭而發生非常奇怪的事情。

作爲一般的最佳做法,我會建議看看一些C++ 11同步功能,如std::mutexstd::lock_guard,這將節省你從你自己,因爲std :: lock_guard釋放自動鎖定,所以你不能忘記,就像在這種情況下,你不能很快無意中做到這一點。這也會讓你的代碼更加便攜。如果你還沒有使用C++ 11,那麼使用升級等價物。