std::map 的线程安全用法
thread-safe usage of std::map
我有一个std::map<int, object*>
,我需要从不同的线程访问(读取和写入)。当然,我可以只使用一个关键部分进行读取和写入,但它会对性能产生巨大影响,因为我有很多find()
调用(每秒几千次)和更少的写入(通常在创建和销毁线程时插入一次和一次擦除)。
因此,我需要使用 CriticalSection
进行写入,并且仅在读取之前检查另一个线程是否正在执行写入操作。但是怎么做呢?我找到了 C++11 和 boost 的解决方案,但我使用的是 Visual Studio 2008(由于兼容性问题)。
有人可以给我一个例子或解释一下如何做到这一点吗?谢谢!
你可以创建一个类来包装你的 std::map 并使用互斥锁锁定写/读函数。使用互斥结构作为此类的成员,并根据每个函数进行适当的锁定/解锁。
Windows API 有一些互斥函数,用于向系统注册互斥句柄。该句柄充当 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 );
}
};
您正在寻找的是多读器/单写入器锁定系统。不幸的是,没有内置类型(在C++14之前)。如果你可以使用boost,那么你可以使用boost的shared_mutex
如果没有,您将不得不自己做(阅读SO上的另一个线程)。您也可以使用MS SRW锁,如T.C.在他的评论中所述(见那里)。
现在,假设您的类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()
- 一个公共的:使用
shared_mutex
的operation()
。
- 从不同线程使用int64的不同字节安全吗
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 虚拟决赛作为安全
- 获取日期异步信号安全吗?如果在信号处理程序中使用,它会导致死锁吗
- 如何将元素添加到数组的线程安全函数?
- C++中的线程安全删除
- 这个指针在c++中的用法
- 通过网络、跨平台传递std::变体是否安全
- 在std::thread中,joinable()然后join()线程安全吗
- 使用std::istream::peek()总是安全的吗
- 从值小于256的uint16到uint8的Endian安全转换
- 使用新线程在类似于 Scott Meyer 的单例习惯用法的实现中实例化单例是否安全?
- std::map 的线程安全用法
- 运算符重载和到布尔的隐式转换与安全布尔习惯用法有关
- 安全enable_shared_from_this用法
- 安全bool习惯用法bool_type(和安全bool习惯用法)是如何工作的
- 常量正确性和安全bool习惯用法
- 在boost中是否有一个安全的bool习惯用法帮助器
- grogroot的这种用法安全吗?
- 安全布尔习惯用法在C++11中已经过时了吗