【发布时间】:2014-10-15 20:28:21
【问题描述】:
假设我们有std::map 容器,我们想让它在插入、擦除、搜索和编辑记录方面是线程安全的。同时我们希望线程可以并行处理不同的记录(读取和编辑记录)。为此,我为记录编辑操作创建了一个单独的类,它使用互斥锁进行保护。
class Data
{
public:
Data(const std::string& data) : _mutex(), _data(data) { }
void setData(const std::string& data)
{
std::lock_guard<std::mutex> locker(_mutex);
_data = data;
}
const std::string& getData() const { return _data; }
private:
std::mutex _mutex;
std::string _data;
};
class Storage
{
public:
void insertData(size_t key, const std::string& data)
{
std::lock_guard<std::mutex> locker(_mutex);
_storage[key] = data;
}
void eraseData(size_t key)
{
std::lock_guard<std::mutex> locker(_mutex);
_storage.erase(key);
}
const std::string& getData(size_t key) const { return _storage[key].getData(); }
void setData(size_t key, const std::string& data) { _storage[key].setData(data); }
private:
std::mutex _mutex;
std::map<size_t, Data> _storage;
};
现在假设线程抓取了要编辑的某些记录的“本地”互斥锁(Data::setData 方法调用)。同时,其他线程抓取“全局”互斥体来删除这条记录(Storage::eraseData 方法调用)——有什么问题吗?这段代码还可能出现什么问题?
【问题讨论】:
-
树型数据结构对多线程根本不友好。
-
我还会查看 TBB 的 threadsafe map 实现作为线程安全容器库的一部分。
-
@PetrPervukhin:他们可以。特别是如果它们被设计为单独锁定节点并且有点草率并且在每次更新时都不平衡。因为如果线程在独立的树节点上运行,它们就不会相互干扰。
-
@ZanLynx:你是对的。但是如果有很多插入/删除,我仍然填写跳过列表会更好。但是我没有测试过它们。
标签: c++ multithreading c++11 mutex