我有一个std::map<int, object*>
我需要从不同的线程访问(读写)。当然,我可以只使用一个关键部分进行读写,但它会对性能产生巨大影响,因为我有很多find()
次调用(每秒几千)并且写入次数少得多(通常,创建和销毁线程时一次插入和一次擦除。)
因此,我需要使用CriticalSection
进行写入,并且只在检查之前检查另一个线程是否正在执行写操作。但是怎么样?
我找到了C ++ 11和boost的解决方案,但我使用的是Visual Studio 2008(因为兼容性问题)。
有人可以给我一个例子或解释如何做吗?谢谢!
答案 0 :(得分:0)
您可以创建一个包装std :: map的类,并使用互斥锁将写/读函数锁定。使用互斥结构作为此类的成员,并根据功能锁定/解锁。
Windows API有一些mutex functions来注册系统的互斥锁句柄。句柄用作Windows识别互斥锁并检查它是否在等待的方式。
这是一个简单的互斥类,可以帮助您开始使用某些Windows API调用。
class MyMutex {
private:
HANDLE m_hMutex;
public:
MyMutex()
{
m_hMutex = CreateMutex(NULL, FALSE, NULL);
}
~MyMutex()
{
CloseHandle(m_hMutex);
}
void Lock()
{
BOOL test = WaitForSingleObject( m_hMutex, INFINITE );
}
void UnLock()
{
ReleaseMutex( m_hMutex );
}
};
答案 1 :(得分:0)
您正在寻找的是多读者/单作家锁定系统。不幸的是,没有内置类型(在C ++ 14之前)。如果你可以使用提升,那么你可以使用提升shared_mutex
如果没有,你必须自己做(在SO上阅读other thread)。您也可以在T.C.的评论中使用MS SRW锁定(请参阅there)。
现在,假设您的班级shared_mutex
已明确定义且可用。您只需将一个shared_mutex
对象作为属性添加到要保护的类中。我建议你在你的类中保持完全无锁的方法,并在它们周围添加包装器,如下所示:
class Whatever;
class MyClass {
boost::shared_mutex mutex;
Whatever find_unlocked() {
whatever blob_blob;
blob_blob = do_whatever_work_find_does();
return blob_blob;
}
void write_smth_unlocked() {
do_something_that_needs_writing_to_MyClass();
}
public:
Whatever find() {
Whatever blob;
mutex.lock_shared(); // Locks for reading (shared ownership on the mutex)
blob = find_unlocked();
mutex.unlock_shared();
return blob;
}
void write_smth() {
mutex.lock(); // Locks for writing (exclusive ownership on the mutex)
write_smth_unlocked();
mutex.unlock();
}
};
这样做将使您能够重用在类的新功能中定义的操作,同时仍然能够通过锁定系统保护整个新操作。
最后,您可以使用两种方法来定义任何操作:
operation_unlocked()
operation()
,它使用shared_mutex
。