【问题标题】:Error with function in multithreaded environment多线程环境中的函数错误
【发布时间】:2013-02-17 20:04:57
【问题描述】:

我的函数所做的是遍历一个布尔数组,并在找到一个设置为 false 的元素时,将其设置为 true。该函数是我的内存管理器单例类中的一个方法,它返回一个指向内存的指针。我收到一个错误,我的迭代器似乎循环并最终从头开始,我相信这是因为多个线程正在调用该函数。

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 变量。没变。错误仍然存​​在。

【问题讨论】:

  • 问题是什么?
  • 所以基本上你是在问多线程/并发是否可能是这个函数不能正常工作的原因?
  • 是的,我想知道这是否是原因以及如何修复该功能
  • 好吧,如果你知道更多的线程可能同时调用这个函数,那么请确保重写和读取你的单例成员的值是同步的。

标签: c++ multithreading memory singleton


【解决方案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,请使用 boost 等价物。

【讨论】:

    猜你喜欢
    • 2015-06-11
    • 2014-08-31
    • 1970-01-01
    • 2012-10-08
    • 2014-10-10
    • 2015-04-05
    • 2018-06-12
    • 1970-01-01
    • 2018-05-10
    相关资源
    最近更新 更多