具有缓存返回值但未锁定的函数

时间:2016-09-27 05:57:58

标签: c++ multithreading

我有一个函数,我想缓存一个返回值,因为它可能需要一段时间才能获取,而且不需要经常更新。目前,我会做这样的事情:

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或者等等。

2 个答案:

答案 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;
}

这样,可以在不保持锁定的情况下复制向量。