【问题标题】:How to sum up elements of a C++ vector "atomically"?如何“原子地”总结 C++ 向量的元素?
【发布时间】:2021-09-12 15:21:57
【问题描述】:

summing up elements of a C++ vector 有多种方式,但如何“原子地”保证这一点?在求和动作期间,向量的元素可能被其他线程修改,导致未知结果。有没有一种无锁的方式来防止向量被修改,直到求和完成?

【问题讨论】:

  • 你能给出一个场景,你可以计算一个过时的向量总和,这个向量(看起来)被其他线程严重改变了?为什么需要无锁?
  • 如果向量很大,那么任何“真正的原子”操作都可能对操作系统产生可怕的后果。
  • 不,没有。根据定义,任何阻止向量被修改的东西都是锁。
  • 我正在多线程上下文中实现滑动窗口限制器。它是通过向量实现的。当一个请求来的时候,我需要对vector求和,判断是否接受当前的请求,如果接受,就会做vector[index]++。
  • 另一种选择是保持流动总和。然后问题将转移到拥有一个原子(且无锁)+=,并确保线程保持更新总和。当然,这只有在总和的变化率不高于读取总和的频率时才有意义。

标签: c++ multithreading c++11 vector thread-safety


【解决方案1】:

在线程之间共享对向量的可变引用可能会导致非常奇怪的错误。例如。读取迭代器可以通过在另一个线程中追加或删除项目来失效。

恕我直言,唯一的解决方案是将向量隐藏在某个层后面,该层记录了修改线程中的插入/删除/更新,这样该线程就不必获取互斥体,因此不会阻塞。一旦它可以获取互斥体,它就可以应用排队的突变。

也就是说,您可以考虑让向量一次只由一个线程拥有和引用,以避免所有这些问题。

【讨论】:

  • 您将如何使用插入/删除/更新来保护日志?您不能在 C++ 模型中抽象出线程同步。
猜你喜欢
  • 2011-03-14
  • 2017-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-28
  • 2019-05-23
  • 2011-11-08
  • 1970-01-01
相关资源
最近更新 更多