gpt4 book ai didi

c++ - 这是缓存线程安全(c++)的通用实现吗?

转载 作者:太空宇宙 更新时间:2023-11-04 15:30:34 25 4
gpt4 key购买 nike

我编写了以下通用缓存的实现,其中 func 将提供值(计算、读取文件等)。 它是线程安全的吗?

#pragma once
#include "stdafx.h"
#include <map>
#include <functional>
#include <mutex>

using namespace std;

template<class T1, class T2>
class __declspec(dllexport) CacheOf
{
map<T1, T2> _cache;
function<T2(T1)> _func;
mutex CacheMtx;
public:
CacheOf(function<T2(T1)> func);
~CacheOf();
T2 Get(T1);
void Clear();
};

template <class T1, class T2>
CacheOf<T1, T2>::CacheOf(std::function<T2(T1)> func)
{
_func = func;
}

template <class T1, class T2>
CacheOf<T1, T2>::~CacheOf()
{
_cache.clear();
}

template <class T1, class T2>
auto CacheOf<T1, T2>::Get(T1 key) -> T2
{

auto it = _cache.find(key);
T2 value;
if (it != _cache.end())
{
value = it->second;
return value;
}
value = _func(key);
{
unique_lock<mutex> cachelock(CacheMtx);
_cache.insert(pair<T1, T2>(key, value));
}
return value;
}

template <class T1, class T2>
auto CacheOf<T1, T2>::Clear() -> void
{
_cache.clear();
}

编辑:对于我将使用这个类的上下文,我添加了这个条件:

for a given key, the value is always the same

我不应该只在 insert 时锁定吗?在插入的同时读取存储在 map 中的某个键值是否可以?让 2 个线程同时执行插入也可以吗(这样我就可以避免使用互斥量)?

我从Butenhoff的书中了解到只有在修改数据的时候才需要用到mutex。因此,在映射中,由于对于给定的键,指向值的指针将始终相同(由于散列函数),因此如果键存在,我不需要锁定。

最佳答案

由于多种原因,此实现不是线程安全的。

GetOf() 的前半部分调用std::map 实例的方法。 std::map 的方法都不是线程安全的,GetOf() 的后半部分修改了 std::map

由于互斥锁不保护 Getof() 的前半部分,即上述方法被调用的地方,这不是线程安全的。

Clear() 也修改了 std::map,也没有任何同步/互斥保护。

附言在析构函数中调用 std::map::clear() 不是必需的。

关于c++ - 这是缓存线程安全(c++)的通用实现吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54337410/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com