我有一个函数,我想缓存一个返回值,因为它可能需要一段时间才能获取,而且不需要经常更新。目前,我会做这样的事情:
std::vector<Foo> getFoos() {
std::lock_guard<std::mutex> lock(m);
std::time_t now = std::time(0);
if (std::difftime(now, oldTime) > CACHE_LIFESPAN) {
cachedVector.empty();
//do something expensive that fills up cachedVector again
oldTime = now;
}
return cachedVector;
}
有什么方法可以在不必锁定整个函数的情况下实现类似的结果吗?
至少,我希望该函数能够有效地无锁,除非需要再次计算 cachedVector
,在这种情况下,任何其他线程都要获得前一个{{1或者等等。
答案 0 :(得分:0)
如果您的编译器符合c ++ 11标准,则可以使用静态线程本地缓存来避免互斥锁,但每个线程执行一次“昂贵的东西”。
有关详细信息,请参阅http://en.cppreference.com/w/cpp/language/storage_duration(thread_local关键字)。
答案 1 :(得分:0)
将cachedVector
更改为std::shared_ptr<std::vector<Foo>>
。然后按如下方式更改代码:
std::vector<Foo> getFoos()
{
std::shared_ptr<std::vector<Foo>> ret;
std::time_t now = std::time(0);
{
std::lock_guard<std::mutex> lock(m);
if (std::difftime(now, oldTime) > CACHE_LIFESPAN)
{
std::vector<Foo> newVector;
//do something expensive that fills up newVector
cachedVector = std::make_shared<std::vector<Foo>>(newVector);
oldTime = now;
}
ret = cachedVector;
}
return *ret;
}
这样,可以在不保持锁定的情况下复制向量。