gpt4 book ai didi

C++ 线程安全括号运算符代理

转载 作者:行者123 更新时间:2023-11-28 05:44:21 25 4
gpt4 key购买 nike

给定一个围绕标准 vector 的简单包装器,为了能够像往常一样设置内容,以线程安全的方式实现 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;
};

这已经够了吗?还是我遗漏了什么东西会把我的腿炸掉?

最佳答案

一旦有了 operator->(这非常有用),您将需要返回一个 -> 代理,它会将锁的生命周期延长到语句结束,并公开你单线程死锁。

看看线程安全的 monads/functor/wrapper,比如 the one here .它不会使锁完全透明,但它们不应该

  • 不要在线程间共享数据

  • 如果您共享数据,请使其不可变

  • 如果必须改变它,通过已知安全设计的瓶颈隔离访问。一个消息队列说。

  • 如果做不到,考虑重新设计

  • 真的。也许是原子的?

  • 有一组有限的函数来显式管理锁

  • 好的,现在用简单的复合操作将读写器 monad 包装起来

  • 编写神奇地获得锁并看起来就像非线程交互代码的代码,从而使您的读者陷入安全和高效的错觉中

降低偏好。

线程安全的危险和困难的部分不是语法笨拙这一事实。正是基于锁的线程安全几乎不可能被证明是正确和安全的。使语法更易于使用并不是一个高值(value)的目标。

例如,v[i]=v[i+1] 充满了缺乏同步:在读取和写入之间任何东西都可能发生变化。更不用说“i 是有效索引了吗?”

关于C++ 线程安全括号运算符代理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36510763/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com