在这种情况下,我应该使用 lock_guard、scoped_lock 还是 unique_lock?

pob*_*oby 6 c++ mutex c++17 lock-guard

我已经阅读了许多已经回答的与此相关的问题,但没有一个让我清楚地了解当我有多个作者但只有一个读者时应该使用哪个。下面的代码是我正在谈论的一个人为的例子。

struct StateInfo {
    long wd{};
    uint32_t perc{};
};

class Blah 
{
    const int numDevices = getDevices();
    std::shared_mutex sharedMutexSI_;
    vector<StateInfo> stateInfo;
public:

    Blah() : stateInfo(numDevices){};

    void writers(StateInfo &newSi, const int i)
    {
        std::shared_lock<std::shared_mutex> _MULTIPLE(sharedMutexSI_);
        stateInfo[i] = newSi;
    }

    StateInfo reader(const int i)
    {
        std::lock_guard<std::shared_mutex> _EXCLUSIVE(sharedMutexSI_);
        return stateInfo[i];
    }
};
Run Code Online (Sandbox Code Playgroud)

情况是多个编写者可能同时更新 stateInfo 向量,但永远不会更新向量中的相同项,因为i每个线程都是唯一的。单个读取器线程可以随时尝试读取任何向量项。

  1. 上面的代码在避免竞争条件方面是否正确?

  2. lock_guard正确使用还是我应该使用scoped_lockunique_lock

ana*_*lyg 2

总结一下评论中已经写的内容:

是的,代码是正确的。但是,它可能效率低下,因为它不允许在写入另一个数组元素时读取任何数组元素。您可能希望通过对每个数组元素使用 a 来进行更细粒度的同步mutex

class Blah 
{
    const int numDevices = getDevices();
    std::vector<std::mutex> mutexes;
    std::vector<StateInfo> stateInfo;
public:

    Blah() : mutexes(numDevices), stateInfo(numDevices){}

    void writers(StateInfo &newSi, const int i)
    {
        std::lock_guard<std::mutex> guard(mutexes[i]);
        stateInfo[i] = newSi;
    }

    StateInfo reader(const int i)
    {
        std::lock_guard<std::mutex> guard(mutexes[i]);
        return stateInfo[i];
    }
};
Run Code Online (Sandbox Code Playgroud)