【发布时间】:2016-04-08 23:11:55
【问题描述】:
给定一个标准向量的简单包装器,以线程安全的方式实现operator[] 以便能够像往常一样设置内容的好方法是什么?
struct bracket_operator_proxy;
struct example
{
auto operator[](size_t i) const { return bracket_operator_proxy(v, m, i); }
private:
std::vector<double> v;
std::mutex m;
};
这是我对bracket_operator_proxy 的快速而天真的尝试:
struct bracket_operator_proxy
{
bracket_operator_proxy(std::vector<double>& v, std::mutex& m, int i)
: v(v), m(m), i(i) {}
operator double() const
{
std::lock_guard<std::mutex> l(m);
return v[i];
}
auto operator=(double d)
{
std::lock_guard<std::mutex> l(m);
v[i] = d;
return d;
}
//... further assignment operators ...
private:
std::vector<double>& v;
std::mutex& m;
int i;
};
这已经足够了吗?还是我错过了什么会炸掉我的腿?
【问题讨论】:
-
您目前禁止
(example[i] = 4.2) = 42;作为您的operator =返回double而不是bracket_operator_proxy&。不是陷阱。 -
@Jarod42:是的,这就是意图。否则,我认为,我必须解锁析构函数中的互斥锁。有什么更好的选择吗?
-
互斥锁在
operator=末尾解锁,所以返回bracket_operator_proxy&应该没问题。 BTWstd::vector<std::atomic<double>>似乎是一个不错的选择。 -
我在您的代码中看不到任何缺陷
-
和@Jarod42 一样,我也会使用std::vector<:atomic>>。在不影响相同矢量元素的情况下允许并发工作,更少的编码(和更少的出错机会)。
标签: c++ multithreading concurrency