我有可以使用以下模板访问的类集合:
template <typename T> using RegistryMap = std::unordered_map <std::string, T *>;
template <typename T> class Registry {
static RegistryMap<T> registry;
public:
static T* get(const std::string& name) {
auto it = registry.find(name);
return it == registry.end() ? nullptr : it->second;
}
static const RegistryMap<T>& getAll() {
return registry;
}
static bool add(const std::string &name, T *object) {
T* &store = registry[name];
if (store)
return false;
else {
store = object;
return true;
}
}
static bool remove(const std::string &name) {
auto it = registry.find(name);
if (it == registry.end())
return false
else {
registry.erase(it);
return true;
}
}
};
此注册表中的许多类都定义了一个名为 run 的方法,线程线程将调用该方法进行紧密循环。当发生这种情况时,其他线程可能会使用上述方法从 map 中添加/删除元素。
void workerThread() {
examples = Registry<ExampleClass>::getAll();
auto it = examples.begin();
while (true) {
if (it != examples.end())
it++->second->run();
else
it = examples.begin();
}
}
有没有办法让这个模板线程安全?我可以向 Registry 模板类添加一个静态锁,并在添加或删除方法中获取它。但是我该如何处理紧密循环的线程呢?特别是在注册表增长非常大的情况下。愿意更换 unordered_map 并在必要时丢失线性查找时间。
最佳答案
一个简单的方法是使用循环链表。这根本不需要锁定 - 只需确保插入和删除是列表本身的原子操作(实现起来很简单)。
如果线性查找很重要,可以通过在键(字符串...)和列表中的链接之间保存一个映射来扩展解决方案,以便于删除或任何其他操作。
关于c++ - 被连续迭代的线程安全无序映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30469467/