Data structures 哪种数据结构最适合以无等待的方式并发插入和有条件地删除项?

Data structures 哪种数据结构最适合以无等待的方式并发插入和有条件地删除项?,data-structures,concurrency,language-agnostic,network-programming,Data Structures,Concurrency,Language Agnostic,Network Programming,我目前正在网络上存储传出TCP和UDP数据包的IP地址和端口。我监视网络并等待对这些数据包的响应 通过搜索IP地址和端口列表以查找过去的出站数据包,首先检查进入网络的每个数据包,看它是被请求的还是未被请求的 目前,我使用一个动态数组,该数组被锁定,然后搜索到达网络的每个数据包。在我们升级到100 mbps服务之前,这一切都很好。在高峰期,我们的探查器显示搜索函数中存在很多争用 查看许多不同的算法,我没有发现多少适合这种特殊类型的使用。我已经了解了原子插入和原子访问的大部分细节,总体来说非常简单

我目前正在网络上存储传出TCP和UDP数据包的IP地址和端口。我监视网络并等待对这些数据包的响应

通过搜索IP地址和端口列表以查找过去的出站数据包,首先检查进入网络的每个数据包,看它是被请求的还是未被请求的

目前,我使用一个动态数组,该数组被锁定,然后搜索到达网络的每个数据包。在我们升级到100 mbps服务之前,这一切都很好。在高峰期,我们的探查器显示搜索函数中存在很多争用

查看许多不同的算法,我没有发现多少适合这种特殊类型的使用。我已经了解了原子插入和原子访问的大部分细节,总体来说非常简单

我在想,首先复制数组,搜索它,删除找到的项,并对两个数组引用/指针进行比较和交换,可能是一种改进。如果CAS成功了,那就去吧。如果没有,则重新进行,直到完成为止

然而,这是非常严重的内存负担,我想这可能会降低性能。我们有很多内存可供使用,但我相信在高峰时期,会有很多CAS故障


我将致力于这个实现来做一些评测,但我很好奇是否有其他人提出了这个问题的解决方案,并愿意与大家分享。任何语言中的示例都很好,尽管我使用的是C和C#。

听起来您有一个包含所有过去IP地址和端口的数组,还有多个进程访问它。这就解释了“搜索上的争用”:不是两个搜索之间的争用,而是在其他进程写入整个数组时对任何搜索的争用


我想像B型树这样的东西可以缓解你的问题。搜索时间从O(N)下降到O(logn),写操作只会更改一小部分数据(从而导致争用)。很可能已经有了专门针对IP地址和端口的B-树变体数据结构和算法;这似乎有点类似于存储转发开关。看起来很接近的一篇文章是

听起来你有一个包含所有过去IP地址和端口的单一阵列,还有多个进程访问它。这就解释了“搜索上的争用”:不是两个搜索之间的争用,而是在其他进程写入整个数组时对任何搜索的争用


我想像B型树这样的东西可以缓解你的问题。搜索时间从O(N)下降到O(logn),写操作只会更改一小部分数据(从而导致争用)。很可能已经有了专门针对IP地址和端口的B-树变体数据结构和算法;这似乎有点类似于存储转发开关。一篇看起来很接近的论文是

我宁愿使用字典数据结构来解决你的问题。你可以使用
或者创建自己的并使用无锁链表(web中有很多引用)来处理冲突。

我宁愿使用字典数据结构来解决您的问题。你可以使用
或者创建自己的并使用无锁链表(web中有很多引用)来处理冲突。

您的解决方案如何处理一个IP地址可以与多个端口关联的事实?如果使用
ConcurrentDictionary
访问列表时会遇到问题,仍然需要锁定列表;字典中每个
KeyValuePair
Value
属性中的任何数据结构都会发生这种情况。在某个时候,您必须锁定整个字典、每个列表、每个节点或每个指针(使用CAS)。这将取决于您的应用程序以及您要花费多少时间对其进行编码(.net没有无锁列表)。无锁DS很难编码,无等待DS甚至更糟糕。此外,在很多情况下,他们的表现都很差。正如我之前所说,我建议您使用无锁列表或基于锁的列表。我认为这将是对您当前解决方案的改进。您的解决方案如何处理一个IP地址可以与多个端口关联的事实?如果使用
ConcurrentDictionary
访问列表时会遇到问题,仍然需要锁定列表;字典中每个
KeyValuePair
Value
属性中的任何数据结构都会发生这种情况。在某个时候,您必须锁定整个字典、每个列表、每个节点或每个指针(使用CAS)。这将取决于您的应用程序以及您要花费多少时间对其进行编码(.net没有无锁列表)。无锁DS很难编码,无等待DS甚至更糟糕。此外,在很多情况下,他们的表现都很差。正如我之前所说,我建议您使用无锁列表或基于锁的列表。我认为这将是对您当前解决方案的改进。