并发skiplist读锁定

时间:2012-10-02 16:05:30

标签: c# multithreading algorithm .net-4.0

我会尽量使这个问题变得通用,但我会简要介绍一下我的实际问题 -

我正在尝试为优先级队列实现并发跳转列表。每个“节点”具有一个值和一个“前向”节点数组,其中node.forward [i]表示跳过列表的第i个级别的下一个节点。对于写访问(即插入和删除),我使用一个Spinlock(仍然确定这是否是最好的锁使用)

我的问题基本上是,当我需要遍历的读访问权时,

node = node.forward[i]

在这样的事情上我需要什么样的线程安全?如果另一个线程正在我读取的同时修改node.forward [i](没有用于读取的当前锁定机制),那么会发生什么?

我最初的想法是在转发的索引器的getter和setter上有一个ReaderWriterLockSLim。在这种情况下是否会有太多不必要的锁定?

编辑:或者最好是为我的所有读取使用Interlocked.Exchange?

1 个答案:

答案 0 :(得分:3)

  

如果另一个线程正在我读取的同时修改node.forward [i](没有用于读取的当前锁定机制),那么会发生什么?

这实际上取决于实施。设置“forward”时可以使用Interlocked.Exchange,以防止引用无效(因为它可以使“set”原子化),但不保证你会得到哪个引用读。然而,通过简单的实现,任何事情都可能发生,包括获取不良数据。

  

我最初的想法是在转发的索引器的getter和setter上有一个ReaderWriterLockSLim。

这可能是一个很好的起点。使用ReaderWriterLockSlim进行正确同步的集合相当容易,而功能始终是第一优先。

这可能是一个很好的起点。

  

在这种情况下是否会有太多不必要的锁定?

没有看到你如何实现它,没有办法知道,更重要的是,它是如何使用的。根据您的使用情况,您可以在此时分析并寻找的优化机会

在旁注 - 您可能希望重新考虑使用node.Forward[i]而不是更多的“链接列表”方法。对Forward[i]的任何访问都可能需要相当多的同步才能遍历跳过列表i步骤,如果在{{1}之间的任何位置存在并发写入,则所有步骤都需要一些同步来防止错误超出node的{​​}}和i个元素。如果只向前看一步,则可以(可能)减少所需的同步量。