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