我想做这样的事情:
class BlockingVector{
protected:
std::vector<int> m_vector;
std::mutex m_mutex;
public:
int & operator [](size_t p_index){
std::lock_guard<std::mutex> lock(m_mutex);
return m_vector[p_index];
}
};
我知道,这是完全错误的。 有没有办法用互斥量重载运算符 []?
正如 Nikos C 所说:它返回对元素的引用,而不是拷贝。因此使用该元素不是线程安全的。
最佳答案
您可以定义一个“locked_reference”辅助类,它在其构造函数中获取锁并在析构函数中释放锁,并将其用作 operator[] 的返回值:
template<class T> class BlockingVector{
private:
std::vector<T> m_vector;
std::recursive_mutex m_mutex;
class locked_ref {
T &ref
lock_guard<std::recursive_mutex> lock;
public:
locked_ref(T &r, std::recursive_mutex &m) : ref(r), lock(m) {}
locked_ref(locked_ref &&) = default;
const T &operator=(const T &v) const { return ref = v; }
operator T() const { return ref; }
};
public:
locked_ref operator [](size_t p_index){
return locked_ref(m_vector[p_index], m_mutex); }
};
您需要一个 recursive_mutex,因为线程需要多次锁定它以评估类似以下内容:
v[i] = v[j] + v[k];
如果两个线程同时对两个 vector 进行操作,则存在死锁的危险。
关于c++ - 运算符 [] 中的互斥量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47503928/