Я написал следующую реализацию универсального кэша, где 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();
}
РЕДАКТИРОВАТЬ: Для контекста я буду использовать этот класс, я добавляю следующее условие:
для данного ключа,значение всегда одинаково
Разве я не должен блокироваться только при I insert
?Хорошо ли читать определенное значение ключа, хранящееся на карте, при одновременной вставке?Также хорошо, что 2 потока одновременно выполняют вставку (поэтому я могу избежать использования мьютекса)?
Насколько я понимаю из книги Бутенхоффа, нам нужно использовать мьютекс только тогда, когда мы изменяемданные.Поэтому в карте из-за того, что для данного ключа указатель на значение всегда будет одинаковым (благодаря хэш-функции), поэтому, если ключ существует, мне не нужно блокировать.