如何“原子地”总结 C++ 向量的元素?

Posted

技术标签:

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

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

【问题讨论】:

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

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

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

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

【讨论】:

您将如何使用插入/删除/更新来保护日志?您不能在 C++ 模型中抽象出线程同步。

以上是关于如何“原子地”总结 C++ 向量的元素?的主要内容,如果未能解决你的问题,请参考以下文章

C++常用STL总结

C++ 字符串向量和数组的一些术语

C++ 字符串向量和数组的一些术语

C++ 字符串向量和数组的一些术语

C++ 字符串向量和数组的一些术语

C++ 如何制作二维向量函数?