You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何无需手动加解锁安全获取需锁保护的类成员容器?

如何安全获取受CRITICAL_SECTION保护的类成员容器?

请问如何从外部正确获取受锁保护的类成员容器?
若使用CRITICAL_SECTION进行锁保护,写入类成员的代码如下:

EnterCriticalSection(&m_cs);
// 写入操作
LeaveCriticalSection(&m_cs);

但当需要从该容器中查找当前存储的数据时,我能想到的方法是为包含容器的类定义Lock、Unlock成员函数,在调用Get前后分别调用它们:

void Lock(){ EnterCriticalSection(&m_cs); }
std::map<unsigned long long, CObject>& Get() { return m_mapObject; }
void Unlock(){ LeaveCriticalSection(&m_cs); }

这种方式容易出错,似乎并不妥当。

我想要的方案需要结合以下两个思路:

  • 类变量外部只读、内部可读写
  • 返回受锁保护的资源并自动解锁

或许我没能找到合适的搜索关键词。

以下是详细的示例代码:

#include <iostream>
#include <Windows.h>
#include <map>

class CObject
{
private:

    int m_nData;

public:

    CObject()
        : m_nData(0)
    {
    }

    ~CObject()
    {
    }

    void Set(const int _nData) { m_nData = _nData; }
    int Get() { return m_nData; }
};

class CObjectManager
{
private:

    CRITICAL_SECTION m_cs;
    std::map<unsigned long long, CObject> m_mapObject;

public:

    CObjectManager()
        : m_cs{}
        , m_mapObject{}
    {
        InitializeCriticalSection(&m_cs);
    }

    ~CObjectManager()
    {
        DeleteCriticalSection(&m_cs);
    }

    bool Add(const unsigned long long _key, const CObject _object)
    {
        bool bReturn = false;

        EnterCriticalSection(&m_cs);

        if (m_mapObject.find(_key) == m_mapObject.end())
        {
            m_mapObject.insert(std::pair<unsigned long long, CObject>(_key, _object));
            bReturn = true;
        }

        LeaveCriticalSection(&m_cs);

        return bReturn;
    }

    bool Delete(const unsigned long long _key)
    {
        bool bReturn = false;

        EnterCriticalSection(&m_cs);

        std::map<unsigned long long, CObject>::iterator iter = m_mapObject.find(_key);
        if (iter != m_mapObject.end())
        {
            m_mapObject.erase(iter);
            bReturn = true;
        }

        LeaveCriticalSection(&m_cs);

        return bReturn;
    }

    void Lock(){ EnterCriticalSection(&m_cs); }
    std::map<unsigned long long, CObject>& Get() { return m_mapObject; }
    void Unlock(){ LeaveCriticalSection(&m_cs); }
};

void DoSomething(CObject* _pObject)
{
    int a = 10;
}

CObjectManager objectManager{};

DWORD Thread(LPVOID _pParam)
{
    for (unsigned long long i = 0ull; i < 100000ull; ++i)
    {
        CObject object{};
        object.Set(i);
        objectManager.Add(i, object);
    }

    return 0;
}

int main()
{
    CObject object0;
    object0.Set(1);

    CObject object1;
    object1.Set(2);

    bool b = objectManager.Add(3ull, object0);
    bool b1 = objectManager.Add(3ull, object1);
    bool b2 = objectManager.Add(4ull, object1);
    bool b3 = objectManager.Delete(3ull);

    CreateThread(nullptr, 0, &Thread, nullptr, 0, nullptr);
    Sleep(0);

    // Need to get current COject map of CObjectManager
    CObject object2{};
    std::map<unsigned long long, CObject>::iterator iter;

    while (true)
    {
        objectManager.Lock();
        std::map<unsigned long long, CObject> mapObject = objectManager.Get();
        iter = mapObject.find(90000ull);
        if (iter != mapObject.end())
        {
            object2.Set(iter->second.Get());
            objectManager.Unlock();
            break;
        }
        objectManager.Unlock();
    }

    DoSomething(&object2);

    Sleep(2000);

    return 0;
}

欢迎各位提供意见或解答。


内容的提问来源于stack exchange,提问作者YoonSeok OH

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 05:25:52