【问题标题】:Container Thread Safety容器线程安全
【发布时间】:2020-07-02 14:43:00
【问题描述】:

我知道那里列出的容器线程安全主题: https://en.cppreference.com/w/cpp/container

但我想知道:我可以同时使用非常量成员函数和常量成员函数而不阻塞(互斥体)吗? 更具体:

  1. 我可以同时使用 std::vector::push_back 和 std::vector::size 吗?
  2. 我可以同时使用 std::set::insert 和 std::set::size 吗?

这通常没有实际意义,但我不需要我将使用的确切大小结果,我只需要一个 valid 在我调用它时的结果.

附:我的疑虑来自那里:https://www.cplusplus.com/reference/set/set/insert/ 他们说 std::set::insert 的地方

同时访问现有元素是安全的

所以也许获取容器的大小也是安全的。

【问题讨论】:

  • “我不需要我将使用的确切尺寸结果,我只需要在我调用它时的有效结果” - 为了使其工作,尺寸需要在内部原子的,它不是。这与一个线程写入另一个线程读取的任何普通变量相同。

标签: c++11 concurrency stl


【解决方案1】:

stl 容器的主要线程安全规则是,如果多个工作线程正在访问一个共享容器,并且其中至少一个是non-const,那么线程应该同步。如果您不进行任何同步,这将是未定义的行为。

如果您查看 C++ 参考 here for std::vector::size(),它会说:

数据竞赛

容器被访问了。没有被包含的元素被访问: 同时访问或修改它们是安全的。

如前所述,vector 容器将在调用.size() 期间被访问,并且此访问不允许您同时在vector 上调用非常量方法。如果你在通过调用.size() 获得vector 的大小时将一个元素push_back 放入向量中,那么你的程序的行为将是未定义的。

【讨论】:

  • 感谢您的回答。但我认为您的陈述并非绝对正确,因为我们可能会写入“向量”,更改它的元素,并同时使用“大小”。所以我想你的意思是“如果多个工作线程正在访问一个共享容器,并且其中至少一个是修改提到的容器本身(可能是写入容器的副作用) ,线程应该同步”或者我不明白你的说法。
  • @cyrax 一句话概括: 如果两个线程正在访问同一个容器,其中一个正在写入容器,那么你的线程应该是同步的。否则你的程序的行为是不确定的。
  • 你写的是一样的,所以它没有解释任何东西。在我的示例中,一个线程正在使用 operator [] 写入向量,另一个正在调用 const 成员函数 size(),但它们不需要按照容器线程安全主题中的说明进行同步。你同意还是不同意?
  • @cyrax 抱歉我的回复晚了。是的你是对的。在这种情况下,根据标准不需要同步,因为 operator[] 在这里被认为是 const 。我已经更新了我的答案。
猜你喜欢
  • 1970-01-01
  • 2016-05-15
  • 1970-01-01
  • 1970-01-01
  • 2012-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多