Ruby - 不可变对象

8
我有一个高度多线程的Ruby应用程序,其中共享了几个实例变量。对这些变量的写入很少(1%),而读取非常常见(99%)。在您的意见或典型的Ruby方式中,确保这些线程始终看到涉及最新值的最佳方法是什么?以下是我目前想到的一些想法(但在进行全面更新之前,我想听听您的意见):
  • 在读取或写入任何这些变量之前必须使用锁定(来自Java Concurrency in Practice)。这种方法的缺点是,在我的代码中会放置大量的synchronize块,并且我看不到避免它的简单方法。
  • 使用Ruby的freeze方法(请参见此处),虽然它看起来同样麻烦,并且不提供第一种选项所提供的任何同步优势。
这两个选项都非常相似,但希望任何人都可以有更好的想法(或者可以为其中一个想法辩护)。我也可以将对象设为不可变,以便它们在操作中不会被破坏或更改,但我不太了解Ruby,无法自行做出决策,并且此问题似乎认为对象高度可变。

我有一个非常类似的问题,继续研究,如果我找到了什么,我会回复的。祝你好运! - csexton
4个回答

6
使用锁是最合适的方法。您可以观看Jim Weirich在这个主题上的演示:Rubyist应该知道的有关线程的所有内容
此外,冻结对象在这里也无济于事,因为您想要修改这些变量。将它们冻结在原地意味着这些变量将无法再进行任何修改(因此你所说的1%的写操作将失败)。

我亲自参加了这个演讲,感觉非常棒。我强烈推荐大家去观看。 - mwilliams

1

我自己没有使用过,但你可能想要查看Dataflow。它使所有变量只能写入一次。


0

读写锁是一个常见的问题,有明确定义的解决方案:

读者-写者锁

而且有很多实现方法:

写入锁模式

你不想为每个读/写操作都加锁。


是的,我之前见过这些锁定设施,但我找不到 Ruby 实现它们的方法。Ruby 有标准锁和监视器,但我找不到实现仅在写入时(或其他变体)保持锁定的方法。 - Chris Bunch

0

你必须使用 Mutex 来同步访问共享状态。实际上,没有任何避免这样做的方法。

在现代多核机器上,你不能对内存访问方式或内存访问与缓存交互方式做出任何假设。


是的,这就是我害怕做的事情。我希望能够找到像billybob所描述的写锁模式,但我找不到Ruby的那种。 - Chris Bunch

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接