如何无需手动加解锁安全获取需锁保护的类成员容器?
如何安全获取受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
相关产品推荐
相关产品推荐

