我已经阅读了许多已经回答的与此相关的问题,但没有一个让我清楚地了解当我有多个作者但只有一个读者时应该使用哪个。下面的代码是我正在谈论的一个人为的例子。
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每个线程都是唯一的。单个读取器线程可以随时尝试读取任何向量项。
上面的代码在避免竞争条件方面是否正确?
是lock_guard正确使用还是我应该使用scoped_lock或unique_lock?
有一个类模板Foo<T>。对于某些特定类型,函数应该使用lock_guard. 这是示例代码:
#include <type_traits>
#include <mutex>
#include <vector>
template<typename T>
class Foo {
public:
void do_something(int k) {
if constexpr(std::is_same_v<T, NeedMutexType>) {
std::lock_guard<std::mutex> lock(mtx_);
}
resource_.push_back(k);
// code for task with resource_ ...
}
private:
std::mutex mtx_;
std::vector<int> resource_;
};
Run Code Online (Sandbox Code Playgroud)
将会std::lock_guard在 if constexpr 范围的末尾被破坏。(如果不正确,请纠正。)
为了处理这个问题,我可以将下面的任务代码复制resource_到 if constexpr 范围中,或者只使用原始的,std::mutex例如mtx_.lock()& mtx_.unlock()。
有什么方法可以处理这个问题std::lock_guard吗?谢谢。