2013-02-17 56 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,那么使用升级等价物。