Что мне следует использовать в этой ситуации lock_guard, scoped_lock или unique_lock?

Я прочитал многие уже отвеченные вопросы, которые касаются этого, но ни один из них не дал мне четкого понимания того, что мне следует использовать, когда у меня есть несколько авторов, но один читатель. Приведенный ниже код является надуманным примером того, о чем я говорю.

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];
    }
};

Ситуация такова, что несколько писателей могут одновременно обновлять вектор stateInfo, но никогда не могут обновлять один и тот же элемент в векторе как iуникален для каждого потока. Один поток чтения может в любое время попытаться прочитать любой из векторных элементов.

  1. Правильно ли приведенный выше код позволяет избежать состояния гонки?

  2. Является lock_guard правильный для использования или я должен использовать scoped_lock или unique_lock?

1 ответ

Решение

Подведем итог тому, что уже было написано в комментариях:

Да, код правильный. Однако это может быть неэффективным, поскольку запрещает чтение из любого элемента массива при записи в другой элемент массива. Возможно, вы захотите выполнить более точную синхронизацию, используя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];
    }
};
Другие вопросы по тегам